CF-394D Physical Education and Buns

来源:互联网 发布:win7如何更改网络位置 编辑:程序博客网 时间:2024/06/07 00:54

题意:

在给定的序列中,改变某些数的值,使他们形成递增的等差数列,求当个数值改变的量尽可能小(k) 输出k,并且输出等差数列首项和公差。

分析:

若形成等差数列 即有:a[n]=a[0]+n*d;-->a[0]=a[n]-n*d;现在把每个值代进去,发现a[0]的值是不一样的。但是要形成等差数列,a[0]必定会一样。所以必须改变每个a[0]*.

从中我们可以选出一个最大的,和一个最小的。发现满足当个值该变量最少,正好是|Max-Min|所以刚好去(Max-Min)/2是最佳选择。故需要枚举公差d,选出最小的改变量k

而公差的范围不会很大,故枚举可以得到答案。另外,很明显d与k的函数关系具有U型关系,这就可以三分查找,得到k了。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std ;const int N=20005;int a[1005];int main(){int i,j,n;int ans,A,d,Max,Min;    while(cin>>n){for(i=0;i<n;i++){cin>>a[i];}sort(a,a+n);ans=N;for(i=0;i<N;i++){Max=-N;Min=N;for(j=0;j<n;j++){Max=max(Max,a[j]-i*j);Min=min(Min,a[j]-i*j);}if((Max-Min+1)/2<ans){ans=(Max-Min+1)/2;A=Min+ans;d=i;}}cout<<ans<<"\n"<<A<<" "<<d<<endl;    } return 0 ;}



0 0
原创粉丝点击