题意:K是由两个素数乘积,如果最小的素数小于L,输出BAD最小的素数,否则输出GOOD
分析 素数打表将 L 大点的素数打出来,一定要比L大,然后就开始枚举,只需K对 素数 取余 看看是否为零,但是 k 是一个很大的数,怎么存储又是一个问题,很好的一个解决方案:用千进制来表示 :加入是 1234567890 表示成 【890】【567】【234】【1】这样存储,如果是十进制对 k 取余,那么就是 从最高位开始 加上 上步*10再取余,放在这里就是*1000
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cmath> 6 using namespace std; 7 const int Max = 1000000 + 10; 8 int primer[Max + 10], flag[Max + 10], tot; 9 char str[10000 + 10]; 10 int Kt[10000], L; 11 void get_primer() 12 { 13 tot = 0; 14 memset(flag, 0, sizeof(flag)); 15 for(int i = 2; i <= Max; i++) 16 { 17 if(flag[i] == 0) 18 { 19 primer[tot++] = i; 20 for(int j = i; j <= Max / i; j++) 21 flag[i * j] = 1; 22 } 23 } 24 } 25 void PrimeTable(void) 26 { 27 tot=0; 28 primer[tot++]=2; 29 30 for(int i=3;i<=Max;i+=2) //奇偶法 31 { 32 bool flaga=true; 33 for(int j=0;primer[j]*primer[j]<=i;j++) //根号法+递归法 34 if(!(i%primer[j])) 35 { 36 flaga=false; 37 break; 38 } 39 if(flaga) 40 primer[tot++]=i; 41 } 42 return; 43 } 44 45 int Pow(int x, int y) 46 { 47 int ans = 1; 48 while(y--) 49 ans *= x; 50 return ans; 51 } 52 int mod(int a[], int key, int lenkt) //大数取余 53 { 54 int ans = 0; 55 for(int i = lenkt - 1; i >= 0; i--) 56 { 57 ans = (ans * 1000 + a[i]) % key; 58 } 59 return ans; 60 } 61 int main(int argc, char** argv) 62 { 63 get_primer(); 64 while(scanf("%s%d", str, &L) != EOF) 65 { 66 if(strcmp(str,"0") == 0 && L == 0) 67 break; 68 memset(Kt, 0, sizeof(Kt)); 69 int len = strlen(str); 70 int lenkt = 0; 71 for(int i = len - 1; i >= 0; i -= 3) 72 { 73 int t = i, cnt = 0; 74 while(cnt < 3 && t >= 0) 75 { 76 Kt[lenkt] += (str[t] - '0') * Pow(10, cnt); // pow函数是double,会不准,找了天错 77 cnt++; 78 t--; 79 } 80 lenkt++; 81 } 82 int have_find = false; 83 for(int i = 0; primer[i] < L; i++) 84 { 85 if(mod(Kt, primer[i], lenkt) == 0) 86 { 87 have_find = true; 88 printf("BAD %d\n", primer[i]); 89 break; 90 } 91 } 92 if(have_find == false) 93 printf("GOOD\n"); 94 } 95 return 0; 96 }