洛谷 P1217 [USACO1.5]回文质数 Prime Palindromes

P1217 [USACO1.5]回文质数 Prime Palindromes

提交142.57k
通过30.21k
时间限制1.00s
内存限制125.00MB
提交代码 加入收藏
题目提供者FarmerJohn2
难度 普及-
历史分数 100
 提交记录    查看题解

标签

搜索    USACO    高性能

题目描述

因为 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数。

写一个程序来找出范围 [a,b] (5 \le a < b \le 100,000,000)[a,b](5a<b100,000,000)( 一亿)间的所有回文质数。

输入格式

第 1 行: 二个整数 a 和 b .

输出格式

输出一个回文质数的列表,一行一个。

输入输出样例

输入 #1复制
5 500
输出 #1复制
5
7
11
101
131
151
181
191
313
353
373
383

说明/提示

Hint 1: Generate the palindromes and see if they are prime.

提示 1: 找出所有的回文数再判断它们是不是质数(素数).

Hint 2: Generate palindromes by combining digits properly. You might need more than one of the loops like below.

提示 2: 要产生正确的回文数,你可能需要几个像下面这样的循环。

题目翻译来自NOCOW。

USACO Training Section 1.5

产生长度为5的回文数:

1 for (d1 = 1; d1 <= 9; d1+=2) {    // 只有奇数才会是素数
2      for (d2 = 0; d2 <= 9; d2++) {
3          for (d3 = 0; d3 <= 9; d3++) {
4            palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;//(处理回文数...)
5          }
6      }
7  }

 

 

 

 首先,我看了题下面的提示,就想按照提示的方法解这道题。因为右边界的取值范围最大到100000000,所以我考虑到位数可以有以下几种情况:1,3,5,7,9.分类讨论分别写循环就可以列举出这里所有回文数了。

然后因为题目要的是回文质数,所以再加上一个质数的判断函数,是质数就输出就可以了:

按照提示,列举回文数的方法是这样的:

比如说我们需要列举所有九位的回文数,我们需要循环5个数:a,b,c,d,e,把这五个数从0`9进行循环,我们的回文数是这样的:

洛谷 P1217 [USACO1.5]回文质数 Prime Palindromes_第1张图片

那就以此类推,写出其他位数的情况:

 

 1  int l,r,num,abc=0;
 2     cin >> l >> r;
 3     int res[10000];
 4         for (int a = 1; a <= 9; a += 2)//一位
 5         {
 6             num =a;
 7             if (num >= l && num <= r && isp(num))
 8             {
 9                 res[abc] = num;
10                 abc++;
11             }
12         }
13     for (int a = 0; a <= 9; a++)//三位
14     {
15             for (int b = 1; b <= 9; b += 2)
16             {
17                 num =b * 100 + a * 10 + b;
18                 if (num >= l && num <= r && isp(num))
19                 {
20                     res[abc] = num;
21                     abc++;
22                 }
23             }
24     }
25     for (int a = 0; a <= 9; a++)//五位
26     {
27         for (int b = 0; b <= 9; b++)
28         {
29                 for (int c = 1; c <= 9; c += 2)
30                 {
31                     num = c * 10000 + b * 1000 + a * 100 + b * 10 + c;
32                     if (num >= l && num <= r && isp(num))
33                     {
34                         res[abc] = num;
35                         abc++;
36                     }
37                 }
38         }
39     }
40     for (int a = 0; a <= 9; a++)//七位
41     {
42         for (int b = 0; b <= 9; b++)
43         {
44             for (int c = 0; c <= 9; c++)
45             {
46                 for (int d = 1; d <= 9; d+=2)
47                 {
48                         num =   d * 1000000 + c * 100000 + b * 10000 + a * 1000 + b * 100 + c * 10 + d ;
49                         if (num >= l && num <= r && isp(num))
50                         {
51                             res[abc] = num;
52                             abc++;
53                         }
54                 }
55             }
56         }
57     }
58     for (int a = 0; a <= 9; a++)//九位
59     {
60         for (int b = 0; b <= 9; b++)
61         {
62             for (int c = 0; c <= 9; c++)
63             {
64                 for (int d = 0; d <= 9; d++)
65                 {
66                     for (int e = 1; e <= 9; e+=2)
67                     {
68                         num = e * 100000000 + d * 10000000 + c * 1000000 + b * 100000 + a * 10000 + b * 1000 + c * 100 + d * 10 + e;
69                         if (num >= l && num <= r && isp(num))
70                         {
71                             res[abc] = num;
72                             abc++;
73                         }
74                     }
75                 }
76             }
77         }
78     }

 

质数判断函数:

 

 1 int isp(int a)
 2 {
 3     for (int i = 2; i <= floor(sqrt(a));i++)
 4     {
 5         if (a % i == 0)
 6         {
 7             return 0;//能被整除说明不是质数
 8         }
 9     }
10     return 1;
11 }

但是这样子储存在数组中的数据顺序有些乱,因为我是按照它中间那一位数的顺序循环的。所以需要排一下序:

1 sort(res, res + abc);

然后就珂以输出了:

1 for (int z = 0; z <= abc-1; z++)
2     {
3         cout << res[z] << endl;
4     }

最后提交上去一看:

WA,WA,WA……

仔细研究程序发现:

回文数不止有奇数位的,还有偶数位的!!!(真是一个惊天动地的珂学大发现呢!)

赶紧加上:

 1 for (int b = 0; b <= 9; b++)//六位
 2         {
 3             for (int c = 0; c <= 9; c++)
 4             {
 5                 for (int d = 1; d <= 9; d += 2)
 6                 {
 7                     num = d * 100000 + c * 10000 + b * 1000 +b * 100 + c * 10 + d;
 8                     if (num >= l && num <= r && isp(num))
 9                     {
10                         res[abc] = num;
11                         abc++;
12                     }
13                 }
14             }
15         }
16             for (int c = 0; c <= 9; c++)//四位
17             {
18                 for (int d = 1; d <= 9; d += 2)
19                 {
20                     num = d * 1000 + c * 100 + c * 10 + d;
21                     if (num >= l && num <= r && isp(num))
22                     {
23                         res[abc] = num;
24                         abc++;
25                     }
26                 }
27             }
28                 for (int d = 1; d <= 9; d += 2)//两位
29                 {
30                     num = d * 10 +d;
31                     if (num >= l && num <= r && isp(num))
32                     {
33                         res[abc] = num;
34                         abc++;
35                     }
36                 }

大功告成!

附上全部的程序:

  1 #include 
  2 
  3 using namespace std;
  4 int isp(int a)
  5 {
  6     for (int i = 2; i <= floor(sqrt(a));i++)
  7     {
  8         if (a % i == 0)
  9         {
 10             return 0;
 11         }
 12     }
 13     return 1;
 14 }
 15 
 16 int main()
 17 {
 18     int l,r,num,abc=0;
 19     cin >> l >> r;
 20     int res[10000];
 21         for (int a = 1; a <= 9; a += 2)//一位
 22         {
 23             num =a;
 24             if (num >= l && num <= r && isp(num))
 25             {
 26                 res[abc] = num;
 27                 abc++;
 28             }
 29         }
 30     for (int a = 0; a <= 9; a++)//三位
 31     {
 32             for (int b = 1; b <= 9; b += 2)
 33             {
 34                 num =b * 100 + a * 10 + b;
 35                 if (num >= l && num <= r && isp(num))
 36                 {
 37                     res[abc] = num;
 38                     abc++;
 39                 }
 40             }
 41     }
 42     for (int a = 0; a <= 9; a++)//五位
 43     {
 44         for (int b = 0; b <= 9; b++)
 45         {
 46                 for (int c = 1; c <= 9; c += 2)
 47                 {
 48                     num = c * 10000 + b * 1000 + a * 100 + b * 10 + c;
 49                     if (num >= l && num <= r && isp(num))
 50                     {
 51                         res[abc] = num;
 52                         abc++;
 53                     }
 54                 }
 55         }
 56     }
 57     for (int a = 0; a <= 9; a++)//七位
 58     {
 59         for (int b = 0; b <= 9; b++)
 60         {
 61             for (int c = 0; c <= 9; c++)
 62             {
 63                 for (int d = 1; d <= 9; d+=2)
 64                 {
 65                         num =   d * 1000000 + c * 100000 + b * 10000 + a * 1000 + b * 100 + c * 10 + d ;
 66                         if (num >= l && num <= r && isp(num))
 67                         {
 68                             res[abc] = num;
 69                             abc++;
 70                         }
 71                 }
 72             }
 73         }
 74     }
 75     for (int a = 0; a <= 9; a++)//九位
 76     {
 77         for (int b = 0; b <= 9; b++)
 78         {
 79             for (int c = 0; c <= 9; c++)
 80             {
 81                 for (int d = 0; d <= 9; d++)
 82                 {
 83                     for (int e = 1; e <= 9; e+=2)
 84                     {
 85                         num = e * 100000000 + d * 10000000 + c * 1000000 + b * 100000 + a * 10000 + b * 1000 + c * 100 + d * 10 + e;
 86                         if (num >= l && num <= r && isp(num))
 87                         {
 88                             res[abc] = num;
 89                             abc++;
 90                         }
 91                     }
 92                 }
 93             }
 94         }
 95     }
 96         for (int b = 0; b <= 9; b++)//六位
 97         {
 98             for (int c = 0; c <= 9; c++)
 99             {
100                 for (int d = 1; d <= 9; d += 2)
101                 {
102                     num = d * 100000 + c * 10000 + b * 1000 +b * 100 + c * 10 + d;
103                     if (num >= l && num <= r && isp(num))
104                     {
105                         res[abc] = num;
106                         abc++;
107                     }
108                 }
109             }
110         }
111             for (int c = 0; c <= 9; c++)//四位
112             {
113                 for (int d = 1; d <= 9; d += 2)
114                 {
115                     num = d * 1000 + c * 100 + c * 10 + d;
116                     if (num >= l && num <= r && isp(num))
117                     {
118                         res[abc] = num;
119                         abc++;
120                     }
121                 }
122             }
123                 for (int d = 1; d <= 9; d += 2)//两位
124                 {
125                     num = d * 10 +d;
126                     if (num >= l && num <= r && isp(num))
127                     {
128                         res[abc] = num;
129                         abc++;
130                     }
131                 }
132     sort(res, res + abc);
133     for (int z = 0; z <= abc-1; z++)
134     {
135         cout << res[z] << endl;
136     }
137     return 0;
138 }

还有一个方法。我们其实可以先列举出所有5~100000000的整数,然后分别判断是不是回文数,是不是质数,是不是在区间内。因为会超时,所以……还是别试了……78.42秒……

程序:(其实可以直接用++来列举,我这样进行嵌套是为了能一眼看出效率有多么低)(5 100000000时:)

 1 #include 
 2 
 3 using namespace std;
 4 
 5 int isp(int pr)
 6 {
 7     for (int i = 2; i <= floor(sqrt(pr)); i++)
 8     {
 9         if (pr % i == 0)
10         {
11             return 0;
12         }
13     }
14     return 1;
15 }
16 int ishui(int x)
17 {
18     int s=0;
19     if (x % 10 == 0 || x <= 0)
20     {
21         return 0;
22     }
23     while (x > s)
24     {
25         s = s * 10 + x % 10;
26         x /= 10;
27     }
28     if (x == s || s / 10 == x)
29     {
30         return 1;
31     }
32     else
33     {
34         return 0;
35     }
36 }
37 int main()
38 {
39     int s = 0;
40     int l=5, r=100000000;
41     for (int a = 0; a <= 9; a++)
42     {
43         for (int b = 0; b <= 9; b++)
44         {
45             for (int c = 0; c <= 9; c++)
46             {
47                 for (int d = 0; d <= 9; d++)
48                 {
49                     for (int e = 0; e <= 9; e++)
50                     {
51                         for (int f = 0; f <= 9; f++)
52                         {
53                             for (int g = 0; g <= 9; g++)
54                             {
55                                 for (int h = 0; h <= 9; h++)
56                                 {
57                                     for (int i = 0; i <= 9; i++)
58                                     {
59                                         s = a * 100000000 + b * 10000000 + c * 1000000 + d * 100000 + e * 10000 + f * 1000 + g * 100 + h * 10 + i;
60                                         if (isp(s) && ishui(s) && s >= l && s <= r)
61                                         {
62                                             cout << s << endl;
63                                         }
64                                     }
65                                 }
66                             }
67                         }
68                     }
69                 }
70             }
71         }
72     }
73     return 0;
74 }

 

你可能感兴趣的:(洛谷 P1217 [USACO1.5]回文质数 Prime Palindromes)