2014北京邀请赛 B Beautiful Garden

来源:互联网 发布:淘宝卖家怎么改会员名 编辑:程序博客网 时间:2024/05/18 17:26



There are n trees planted in lxhgww's garden. You can assume that these trees are planted along the X-axis, and the coordinate of ith tree is xi.
But in recent days, lxhgww wants to move some of the trees to make them look more beautiful. lxhgww will recognize the trees as beautiful if and only if the distance between any adjacent trees is the same.
Now, lxhgww wants to know what is the minimum number of trees he need to move.
Just to be clear, after moving, there should still be n trees in the X-axis.

Input
The first line of the input contains a single integer T, which is the number of test cases.
For each case,

The first line contains an integers number n (1 ≤ n ≤ 40), representing the number of trees lxhgww planted;
The second line contains n integers numbers, the ith number represents xi. (-1000000000 ≤ xi ≤ 1000000000)

Output

For each case, first output the case number as "Case #x: ", and x is the case number. Then output a single number, representing the minimum number of trees lxhgww needs to move.
Sample Input

1
4
1 3 6 7

Sample Output

Case #1: 1


这个题目给我留下了很深的印象。。比赛的时候没有做出来,原因是思路有问题,方法不够暴力,AC解法是这样的:先用两重循环暴力枚举两个不动的数,再枚举能够将这个区间分成几段,,这样就确定了公差,最后枚举左边的不动数在新序列中是第几个,所以枚举目标序列用了O(n^4),最后是一个对比查找,关键就卡在这里了,后来看到大湿用set维护,算是学到了点新东西了,还有一点,数有重复的,所以要分开讨论

/*AC*/#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#include <set>using namespace std;typedef long long LL;LL a[45];set<LL> s;int main(){    int T, kase=0;    cin>>T;    while(T--){        int n;        cin>>n;        s.clear();        for(int i=0; i<n; i++){            cin>>a[i];            s.insert(a[i]);        }        sort(a, a+n);        int ans = n-1;        for(int i=0; i<=n-2; i++)            for(int j=i+1; j<=n-1; j++){                LL dd = a[j] - a[i];                for(int div = 1; div <= n-1; div++){                    if(dd%div == 0){                        LL d = dd/div;                        if(d == 0){ //特熟情况,单独处理:目标序列的每个数都和原序列中的某个数相等                           int now = 0;                           for(int l=0; l<n; l++)                               if(a[l] != a[i]) now++;                           ans = min(ans, now);                        }                        else{ //目标序列中的数互不相同                            for(int k=0; k+div<=n-1; k++){ //假定a[i]是b[]中第k个数                                int now = 0;                                for(int x=0; x<n; x++){                                    int bx = a[i] + (x-k)*d;                                    if(!s.count(bx)) now++; //从目标序列向原序列映射,查找没有的数                                }                                ans = min(ans, now);                            }                        }                    }                }        }        printf("Case #%d: %d\n", ++kase, ans);    }    return 0;}




0 0