poj2635 同餘定理 + 素數篩法
阿新 • • 發佈:2019-01-06
題意:給定一個數,這個數是兩個素數的乘積,並給定一個限制L,問是否兩個素數中存在小於L的數,若存在輸出較小質數,否則列印‘GOOD’。
思路:
1 . x = a * b, a和b都是素數,那麼x只能分解為(1,x)或則(a,b),因為 x 只有四個因子1,a,b,x。
2 . 判定某大數y能否被x整除,可以通過求餘是否為0判斷。大數求餘的方法在我的上一篇文章中有證明。
3 . 素數打表,方便快速判斷某個數是否為質數。
根據第一個結論,可以知道如果某個素數(這個數小於限制L)能被大數整除,那麼這個數就是最小質數,就可以結束判斷。
AC程式碼
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int maxn = 1000005; int vis[maxn], prim[maxn], a[105]; char s[105]; int deal(int n){ int m = sqrt(n + 0.5); memset(vis, 0, sizeof(vis)); for(int i = 2; i <= m; ++i) if(!vis[i]) for(int j = i*i; j <= n; j += i) vis[j] = 1; int cnt = 0; for(int i = 2; i < n; ++i){ if(!vis[i]) prim[cnt++] = i; } return cnt; } // 轉換千進位制 int turn(int n){ memset(a, 0, sizeof(a)); int c = 0; int m = n % 3; for(int i = 0; i < m; ++i) a[c] = a[c] * 10 + s[i] - '0'; if(m) ++c; for(int i = m; i < n; i += 3){ for(int j = i; j < i + 3; ++j) a[c] = a[c] * 10 + s[j] - '0'; ++c; } return c; } bool mod(int x, int n) { int m = 0; for(int i = 0; i < n; ++i){ m = (m * 1000+ a[i]) % x; } if(m == 0) return true; return false; } int main(){ int n = deal(maxn); int h; while(scanf("%s%d", s, &h) == 2 && h){ int len = strlen(s); len = turn(len); int flag = 1; for(int i = 0; prim[i] < h && i < n; ++i) { if(mod(prim[i], len)) { printf("BAD %d\n", prim[i]); flag = 0; break; } } if(flag) printf("GOOD\n"); } return 0; }
如有不當之處歡迎指出!