数论,千进制,高精度求模+同余模定理
原题连接:http://poj.org/problem?id=2635
题意:给定一个大数K,K是两个大素数的乘积。
然后给定一个int内的数L。
求这两个大素数中最小的一个是否小于L,如果小于则输出这个素数。
思路:
1.Char格式读入k,然后把k转换为千进制kt,同时变为int型。(加快运算效率)。
例如:k=1234567变为千进制就为:kt = [ 1][234][567].
为了方便,代码使用的是“局部有序,全局倒序”存放kt,即kt = [567][234][1 ]
2.素数打表。
注意打表的范围要比10^6大,否则当L = 10^6时会数组越界。
3.高精度求模
123对3取模可以通过同余模定理对大数‘分块’间接求模。
先求1%3 = 1;
然后(1*10+2)%3=0;
最后(0*10+3)%3 = 0;
那么就得到123%3 = 0;
在千进制下只需将*10改为*1000即可。
参考博客:http://blog.csdn.net/lyy289065406/article/details/6648530
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int Max = 1000050; int Kt[10000]; //千进制的K int L; int prime[Max]; //素数打表 void PrimeTable(void){ int num = 0; prime[num++]=2; for(int i = 3 ; i <=Max;i+=2) { bool flag = true; for(int j = 0 ; prime[j]*prime[j]<=i;j++) { if(!(i%prime[j])) { flag = false; break; } } if(flag) prime[num++]=i; } return ; } //高精度k对p求模 bool mod(const int*k,const int p,const int len) { int sq = 0; for(int i = len-1;i>=0;i--) //千进制k是逆序存放 { sq = (sq*1000+k[i])%p; //同余模定理 } if(!sq) //k能整除p return false; else return true; } int main(){ PrimeTable(); char K[10000]; while(cin>>K>>L&&L) { memset(Kt,0,sizeof(Kt)); int lenK = strlen(K); for(int i = 0 ; i < lenK;i++) //把k转换为千进制kt,其中kt局部顺序,全局倒序 { //如k = 1234567 = [ 1]234][567],则kt = [567][234][1 ] int pkt = (lenK+2-i)/3-1; Kt[pkt] = Kt[pkt]*10+(K[i]-'0'); } int lenkt = (lenK+2)/3; bool flag = true; int pMin = 0; while(prime[pMin]<L) { if(!mod(Kt,prime[pMin],lenkt)) //判断KT能否被prime[pMin]整除 { flag = false; cout<<"BAD "<<prime[pMin]<<endl; break; } pMin++; } if(flag) cout<<"GOOD"<<endl; } return 0; }
17:15:42

浙公网安备 33010602011771号