这题特别好理解,就是代码坑啊。题意就是给一个数,这个数是两个大素数的积,再给出一个数,如果最小的素数比给的数大,打印GOOD,否则打印BAD和最小的素数。
这题用的方法是高精度求模+同余模定理。还有素数打表,把10^6内的素数全部预打表,在求模时则枚举到小于L为止。注意打表不能只打到100W,要保证素数表中最大的素数必须大于10^6。千进制的性质与十进制相似。例如,把K=1234567转成千进制,就变成了:Kt=[ 1][234][567]。为了方便处理,按“局部有序,全局倒序”的方式存放Kt中即Kt=[567][234][1 ] 。
代码如下
#include<stdio.h>
#include<string.h>#include<stdlib.h>
#define Range 1000100
int Kt[10000];
int L;
int prime[Range+1];
void PrimeTable()
{
int pNum=0;
int i,j,flag;
prime[pNum++]=2;
for(i=3;i<=Range;i+=2)
{
flag=1;
for(j=0;prime[j]*prime[j]<=i;j++)
if(!(i%prime[j]))
{
flag=0;
break;
}
if(flag==1)
prime[pNum++]=i;
}
return;
}
int mod(const int* K,const int p,const int len)
{
int sq=0;
int i;
for(i=len-1;i>=0;i--)
sq=(sq*1000+K[i])%p;
if(!sq)
return 0;
return 1;
}
void main()
{
char K[10000];
int i,lenK,pKt,lenKt,pMin,flag;
PrimeTable();
while(scanf("%s %d",K,&L)!=EOF&&L!=0)
{
memset(Kt,0,sizeof(Kt));
lenK=strlen(K);
for(i=0;i<lenK;i++)
{
pKt=(lenK+2-i)/3-1;
Kt[pKt]=Kt[pKt]*10+(K[i]-'0');
}
lenKt=(lenK+2)/3;
flag=1;
pMin=0;
while(prime[pMin]<L)
{
if(mod(Kt,prime[pMin],lenKt)!=1)
{
flag=0;
printf("BAD %d\n",prime[pMin]);
break;
}
pMin++;
}
if(flag==1)
printf("GOOD\n");
}
}