本题中首先是要把M转化为大于等于N的最小素数M’
我用了筛法打素数表,我认为M<=10000不代表M‘也<=10000。比10000小的最大素数是9973,比10000大的最小素数是10007。
则筛法以2-103为宜(素数103^2>10007)而非2-97(素数97^2<9973)
打完表后就可以求得M’
然后再用二次探测法。注意二次探测法在不同的地方表述的细节有所不同,我在程序中是设(k+j^2)%M k<M 没有k-j^2
程序如下:
#include<stdio.h>
const int MAX=10010;
int p[MAX];
int azu[MAX];
int num[MAX];
int array[27]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103};
void prime()
{
int i,j;
p[1]=1;
for(i=0;i<27;i++)
for(j=2;;j++)
if(array[i]*j<MAX)
p[array[i]*j]++;
else
break;
}
int main()
{
prime();
int m,n,x,i,y,j;
scanf("%d %d",&m,&n);
if(p[m])
{
while(p[m])
m++;
}
for(i=0;i<n;i++)
{
scanf("%d",&x);
y=x%m;
j=0;
while(azu[y])
{
if(j>=m)
break;
j++;
y=(x+j*j)%m;
}
if(!azu[y])
{
azu[y]++;
num[i]=y;
}
else
{
num[i]=-1;
}
}
for(i=0;i<n;i++)
{
if(i)
printf(" ");
if(num[i]==-1)
printf("-");
else
printf("%d",num[i]);
}
printf("\n");
return 0;
}