题目:http://poj.org/problem?id=2635
高精度求模 同余模定理。
题意:
给定一个大数K,K是两个大素数的乘积的值。再给定一个int内的数L
问这两个大素数中最小的一个是否小于L,如果小于则输出这个素数。
思路:
Char格式读入K。把K转成千进制Kt,同时变为int型。
把数字往大进制转换能够加快运算效率。若用十进制则耗费很多时间,会TLE。千进制的性质与十进制相似。
例如,把K=1234567890转成千进制,就变成了:Kt=[ 1][234][567][890]。 //不过我现在还不明白为什么不是123 456 789 0
当123是一个大数时,就不能直接求,只能通过同余模定理对大数“分块”间接求模
具体做法是:
先求1%3 = 1
再求(1*10+2)%3 = 0
再求 (0*10+4)% 3 = 1
那么就间接得到124%3=1,这是显然正确的
而且不难发现, (1*10+2)*10+4 = 124
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 6 int p[1001000]; 7 int kt[35],l,lenkt; 8 void prime() 9 { 10 int i,j; 11 memset(p,-1,sizeof(p)); 12 p[0]=p[1]=0; 13 for(i=3; i<1001000; i++) 14 { 15 if(i%2==0) p[i]=0; 16 if(p[i]) 17 for(j=i*2; j<1001000; j+=i) 18 p[j]=0; 19 } 20 //cout<<p[31]<<endl; 21 } 22 23 int check() 24 { 25 int i=2,j,mo; 26 while(i<l) 27 { 28 mo=0; 29 if(p[i]) 30 { 31 for(j=1; j<=lenkt; j++) 32 mo=(mo*1000+kt[j])%i; 33 if(mo==0) 34 return i; 35 } 36 i++; 37 } 38 return 0; 39 } 40 41 int main() 42 { 43 prime(); 44 char s[110]; 45 int i,j,len,x,y; 46 int cnt; 47 while(cin>>s>>l&&(strcmp(s,"0")!=0||l!=0)) 48 { 49 len=strlen(s); 50 j=0; x=1; 51 memset(kt,0,sizeof(kt)); 52 53 y=len%3; 54 if(y==0) 55 lenkt=len/3; 56 else 57 { 58 lenkt=len/3+1; 59 for(i=0; i<y; i++) 60 kt[x]=kt[x]*10+s[i]-48; 61 x++; 62 } 63 for(i=y; i<=len-1; i++) 64 { 65 kt[x]=kt[x]*10+s[i]-48; 66 j++; 67 if(j%3==0) 68 x++; 69 } 70 //cout<<lenkt<<" "<<kt[1]<<" "<<kt[2]<<endl; 71 cnt=check(); 72 if(cnt) 73 printf("BAD %d ",cnt); 74 else 75 printf("GOOD "); 76 } 77 return 0; 78 }