HDOJ1431 素數迴文 --- 快速素數篩+打表
阿新 • • 發佈:2018-12-17
Problem Description xiaoou33對既是素數又是迴文的數特別感興趣。比如說151既是素數又是個迴文。現在xiaoou333想要你幫助他找出某個範圍內的素數迴文數,請你寫個程式找出 a 跟b 之間滿足條件的數。(5 <= a < b <= 100,000,000);
Input 這裡有許多組資料,每組包括兩組資料a跟b。
Output 對每一組資料,按從小到大輸出a,b之間所有滿足條件的素數迴文數(包括a跟b)每組資料之後空一行。
Sample Input
5 500
Sample Output
5 7 11 101 131 151 181 191 313 353 373 383
因為要在大範圍內查詢素數,所以採用快速素數篩,迴文數的話直接手動轉置判斷是否和原來的數相等就可以了。
因為給定的範圍大,直接做會超時,所以先在本地算出結果觀察規律。
最後發現1億以內的迴文素數最大為9989899,不到1千萬,相當於9989899以後的數都不用判斷了,瞬間資料規模就下降了一個指數級。
用flag陣列來標記迴文素數,先素數篩,false表示是素數,然後在素數中判斷迴文,如果不是迴文,標記改為true.
這樣flag陣列中標記為false的就是迴文素數。(當然也可以直接把本地跑出來的結果放在數組裡打表)
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; bool flag[9989900];// false表示是素數 // 素數篩 void Init() { memset(flag,0,sizeof(flag)); for(int i = 2;i <= 9989899;i++) { if(flag[i] == false) { for(int j = 2*i;j <= 9989899;j += i) { flag[j] = true; } } } } // 判斷x是否是迴文數 bool IsPalindrome(int x) { int temp = x; int ret = 0; while(x) { ret = ret * 10 + x % 10; x /= 10; } if(ret == temp) return true; return false; } int main() { Init(); for(int i = 1;i <= 9989899;i++) { if(flag[i] == true) continue; if(!IsPalindrome(i)) flag[i] = true; } int a,b; while(scanf("%d%d",&a,&b) != EOF) { if(b > 9989899) b = 9989899; for(int i = a;i <= b;i++) { if(flag[i] == false) printf("%d\n",i); } printf("\n"); } return 0; }