cf D. Physical Education and Buns
http://codeforces.com/contest/394/problem/D
题意:给你n个数,然后通过操作使得这n个数变为一个等差数列,操作是可以经过小于等于k次加1或减去1,要使得k尽量小。
思路:通过枚举公差d,然后通过每一个减去相应的个数的d,找到首项,每一个都可以得到一个首项,在这些首项中找到最大值和最小值,我们取最大值和最小值的一半为a1,然后找到一个k,在等到的很多个k中找到最小值。
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 #define maxn 10010 6 using namespace std; 7 const int inf=1<<29; 8 9 int n; 10 int a[maxn],a1,d; 11 12 int main() 13 { 14 while(scanf("%d",&n)!=EOF) 15 { 16 for(int i=0; i<n; i++) 17 { 18 scanf("%d",&a[i]); 19 } 20 sort(a,a+n); 21 int ans=inf; 22 for(int k=0; k<=20002; k++) 23 { 24 int max1=-inf,min1=inf; 25 for(int i=0; i<n; i++) 26 { 27 min1=min(min1,a[i]-i*k); 28 max1=max(max1,a[i]-i*k); 29 } 30 int x=(min1+max1)/2; 31 if(ans>max(x-min1,max1-x)) 32 { 33 ans=max(x-min1,max1-x); 34 a1=x; 35 d=k; 36 } 37 } 38 printf("%d\n",ans); 39 printf("%d %d\n",a1,d); 40 } 41 return 0; 42 }