首页 > 代码库 > 2014 SummerTrain Beautiful Garden

2014 SummerTrain Beautiful Garden

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

141 3 6 7
 

Sample Output

Case #1: 1
 

Source

2014 ACM-ICPC Beijing Invitational Programming Contest
 
 
题意是要用最少的次数改动给出的 N个数使得它成为等差数列。
比赛的时候就一直卡这题,应该是姿势不对,那时候的做法的枚举任意两个数,以他们的差值作为等差数列的d
 
正解是看kuangbin写的,枚举任意两个数,较小的数作为等差数列的首项,然后枚举 x[i],x[j] 所可能构成的 d ,
然后再查一下有多少个x[k]不属于这个等差数列(就是 N-属于的个数)。
 
 
#include <iostream>#include <cstdio>#include <map>#include <algorithm>#include <cstring>using namespace std;typedef long long LL;const int N= 44;int n;LL x[N];map<LL,int>mp;LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);}void run(){        scanf("%d",&n);        for(int i=0;i<n;++i){            scanf("%lld",&x[i]);            if(mp.find( x[i] ) == mp.end() ) mp[x[i]]=1;            else mp[x[i]]++;        }        if( n <= 2){ puts("0"); return ; }        int ans=n-1;        for(int i=0;i<n;++i){            for(int j=i+1;j<n;++j){                LL d=abs(x[j]-x[i]);                if(!d){                    ans=min(ans,n-mp[x[j]]);                    continue;                }                for(int k=1;k<=n-1;++k){                    LL g=gcd((LL)k,d);                    LL c=min(x[i],x[j]);                    LL dis=k/g;                    LL d2=d/g;                    int cnt=0;                    for(int z=0; z < n; z += dis){           //dis~~                        if(mp.find(c) != mp.end()) cnt++;                        c += d2;                    }                    ans = min(ans,n-cnt);                }            }        }        printf("%d\n",ans);}int main(){    //freopen("in.txt","r",stdin);    int cas=1,_;    scanf("%d",&_);    while(_--){                    mp.clear();        printf("Case #%d: ",cas++);        run();        }    return 0;}