http://poj.org/problem?id=2635
高精度取模问题
对于一般的a%b我们可以直接进行运算,但是a现在是一个与10^100接近的大整数,因此我们需要利用同余定理进行求解,即边加边模
对于本题还有一个问题是如果用十进制来取模,运算次数太多会TLE,因此我们将其转化为千进制来减少运算次数
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 1000000 + 100;
bool IsPrime[MAX];
int Prime[MAX],pn;
void MakePrime(){///欧拉筛法
memset(IsPrime, true, sizeof(IsPrime));
IsPrime[0] = IsPrime[1] = false;
pn = 0;
for(int i=2; i<MAX; i++){
if(IsPrime[i]) Prime[pn++] = i;
for(int j=0; j<pn && Prime[j]*i<MAX; j++){
IsPrime[Prime[j]*i] = false;
if(i % Prime[j] == 0) break;
}
}
}
char str[1010];
int L,num[1010];
bool Check(int len, int mod){
int res = 0;
for(int i = len-1; i>=0; i--)///千进制是局部有序全局倒序存储的
res = (res * 1000 + num[i]) % mod;///边加边模(同余定理应用)
if(res) return true;
return false;
}
int main(){
// freopen("in.txt", "r", stdin);
MakePrime();
while(scanf("%s %d",str, &L) != EOF && L){
int len = strlen(str);
memset(num, 0, sizeof(num));
for(int i=0; i<len; i++){
int id = (len + 2 - i)/3 - 1;///下标技巧处理
num[id] = num[id] * 10 + str[i] - '0';
}
int lenk = len / 3 + ((len % 3) ? 1 : 0);///计算千进制下的新长度
int pMin = 0,flag = 1;
while(Prime[pMin] < L && pMin < pn){
if(!Check(lenk, Prime[pMin])){
flag = 0;
printf("BAD %d\n",Prime[pMin]);
break;
}
pMin++;
}
if(flag) puts("GOOD");
}
return 0;
}