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 }
View Code

 

你可能感兴趣的:(cat)