CodeForces Round #183 (303C) Minimum Modular

    两数a,b同余m,显然(a-b)%m=0.....若有m%p=0...那么(a-b)%p=0....

   将所有的(a[j]-a[i])记录下来...用c[1000000]的表来记...如果一个数p是N对数的同余..那么c[p]=N...

   有了上面的处理,就可以方便的统计出对于当前枚举的md...会产生多少对同余的(将md所有的整数倍c[ ] 加起来)...

   但产生了N对同余的..并不代表要去除N-1个数才行...比如...

   3,6,9,10....(3,6),(3,9),(3,12),(6,9),(6,12),(9,12)...如果当前测试的md=3..那么会有6对同余3的....而实际上最少减去3个数可以保证不出现同余3的情况...

   我做到这里就没想法了...

   看了下别人的代码.. 自己理解了下..很有道理...不过也感觉很大胆...

   其实并不是用md求同余对来计算最少要减去几个数..而是用其剪枝..然后再暴力查找(纯暴力..一个个试..看有多少重复..重复个数是否不大于k)

   剪枝的方式是当前md的同余对>k*(k+1)/2..就找下一个md.... 

   为什么同余对>k*(k+1)/2时就不必要用暴力的方式来判断了?

   考虑一个极端的情况..给的n个数每一个都是md的整数倍..那么显然就有n*(n-1)/2个关于md的同余对...但是只需要去掉n-1个数就可以使得没有同余对了...

   把n-1看成题目要求的k...那么极端情况不就是md的同余对为(k+1)*k/2吗?当md的同余对>(k+1)*k/2,无论如何也要删去k+1个数才能使得没有对于md的同余对出现...

   这个剪枝相当劲爆..虽然每个通过了同余对<=(k+1)*k/2验证的md都要进行一次暴力查找判断...但时间完全ok...


Program:

#include<iostream>
#include<stdio.h>
#include<cmath>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#define ll long long
#define oo 1000000000
using namespace std; 
int a[5005],c[1000005],n;
bool used[1000005];
int main()
{     
       int i,j,k,m; 
       while (~scanf("%d%d",&n,&k))
       {
             for (i=1;i<=n;i++) scanf("%d",&a[i]);
             sort(a+1,a+1+n);
             memset(c,0,sizeof(c));
             for (i=1;i<n;i++)
               for (j=i;j<=n;j++)
                 c[a[j]-a[i]]++; 
             for (i=1;i<=a[n]+1;i++)
             { 
                   m=0;
                   for (j=i;j<=1000000;j+=i) 
                   {
                          m+=c[j];
                          if (m>k*(k+1)/2) goto A;
                   }
                   memset(used,false,sizeof(used));
                   m=0;
                   for (j=1;j<=n;j++)
                   {
                          if (used[a[j]%i]) m++;
                          used[a[j]%i]=true;
                          if (m>k) goto A;
                   }
                   break;
                   A: ;
             }              
             printf("%d\n",i);
       }       
       return 0;
}


原文地址:https://www.cnblogs.com/javawebsoa/p/3091545.html