Description
奶牛们有一个习惯,那就是根据自己的编号选择床号。如果一头奶牛编号是a,并且有0..k-1一共k张床,那么她就会选择a mod k号床作为她睡觉的地点。显然,2头牛不能睡在一张床上。那么给出一些奶牛的编号,请你为她们准备一间卧室,使得里面的床的个数最少。
Input
第一行是奶牛的个数n(1<=n<=5000); 第2到第n+1行是每头奶牛的编号Si(1<=Si<=1000000)。
Output
奶牛们有一个习惯,那就是根据自己的编号选择床号。如果一头奶牛编号是a,并且有0..k-1一共k张床,那么她就会选择a mod k号床作为她睡觉的地点。显然,2头牛不能睡在一张床上。那么给出一些奶牛的编号,请你为她们准备一间卧室,使得里面的床的个数最少。
Input
第一行是奶牛的个数n(1<=n<=5000); 第2到第n+1行是每头奶牛的编号Si(1<=Si<=1000000)。
Output
仅一行,是最少的床的数目。
分析:
题目的意思,是求一个最小的k,使得给定的n个数对它取模的结果都不相同。
同余的一般形式:a≡b(mod k) ,也就是a-b mod k =0,k是a-b的因数。要使a,b不同余,k就不能是a-b的因数。
设一个vis数组,可以先O(n)时间内把所有的a[i]-a[j]标记上,然后k从1开始枚举,若w*k已标记,那么标记vis[w]=1,vis[k]=1,再枚举下一个k。直到找到第一个w*k都没被标记的k,输出。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int INF=1000005;
const int maxn=5005;
int n,vis[INF],a[maxn];
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d",&n);
int maxs=0;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++) maxs=max(maxs,abs(a[i]-a[j])),vis[abs(a[i]-a[j])]=1;
int flag,w,i;
for(i=1;i<=maxs;i++)
{
flag=w=1;
for(;i*w<=maxs;w++)
{
if(vis[i*w])
{
vis[i]=1,vis[w]=1;
flag=0;
break;
}
}
if(flag) break;
}
printf("%d",i);
return 0;
}