1. 程式人生 > >洛谷 P1217 [USACO1.5]回文質數 Prime Palindrome

洛谷 P1217 [USACO1.5]回文質數 Prime Palindrome

line rime name 題目 由於 判斷質數 tps c代碼 nbsp

嗯...

這道題對於蒟蒻的我來說實在是TQL...

先看一下題:(題目鏈接:https://www.luogu.org/problemnew/show/P1217)

然後說一下我的做題過程吧:

一看到是普及-的題,就沒有考慮什麽篩法,只是用最暴力的篩素數的方法做的,然後就導致最後一個點TLE;

接著是一個改進,又用了埃氏篩,可是它太不穩定了,然後數組總是開小,然後就各種TLE,MLE,RE...

最後用的是歐拉篩(線性篩),然後還是最後一個點TLE...然後就很納悶,看了題解之後才發現有這樣的一個東西:

1.偶數位數回文數(除11)必定不是質數(自行百度),所以只要運行到10000000

然後發現將讀入後的b進行一次判斷就可以了,然後這種方法,暴力篩還是TLE,埃氏篩由於不穩定也TLE,最終還是只有歐拉篩(線性篩)好用....

思路:

主要是在a到b的這段區間中先判斷是否為回文數(註意判斷回文數的方法),並且用歐拉篩判斷是否為素數即可...

重難點:

  偶數位數回文數(除11)必定不是質數(自行百度),所以只要運行到10000000

否則會一直TLE(不開O2)

下面是歐拉篩的AC代碼:

 1 #include<cstdio>
 2 #include<iostream>
 3 
 4 using namespace
std; 5 6 int a, b; 7 const int maxn = 10000005; 8 9 int cnt; 10 int prime[maxn]; 11 int vis[maxn]; 12 bool pp[maxn]; 13 14 inline void is_prime(){ 15 for(int i = 2; i <= b; i++){ 16 if(!vis[i]) prime[++cnt] = i, pp[i] = 1; 17 for(int j = 1; j <= cnt && i * prime[j] <= b; j++){
18 vis[i * prime[j]] = true; 19 if(i % prime[j] == 0) break; 20 } 21 } 22 }//歐拉篩判斷質數 23 24 inline int hui_wen(int x){ 25 int t = 0; 26 int y = x; 27 while(y != 0){ 28 t = t * 10 + y % 10; 29 y = y / 10; 30 } 31 if(t == x) return 1; 32 return 0; 33 }//判斷回文數 34 35 int main(){ 36 scanf("%d%d", &a, &b); 37 if(b > 10000000) b = 10000000;//重點 38 is_prime(); 39 for(int i = a; i <= b; i++){ 40 int n = i; 41 if(hui_wen(n) && pp[n] ) printf("%d\n", n); 42 } 43 return 0; 44 }

洛谷 P1217 [USACO1.5]回文質數 Prime Palindrome