洛谷 P1217 回文质数

洛谷 P1217 回文质数_第1张图片

洛谷 P1217 回文质数_第2张图片
思路很简单,主要卡在了运行时间上。本题主要考察数学知识
因为先判断的回文数,搜索素数的次数大大减小,因此函数比筛法要快。如果大量搜索素数,筛法会比函数快很多
需要知道的:
1.偶数位数回文数(除11)必定不是质数(自行百度),所以只要运行到10000000。
2.偶数肯定不是质数。这样至少排除一半多的数据量。
易错样例
输入样例: 5
输出样例: 100000000
最初的代码(普通筛选素数):

#include
using namespace std;
int prime(int n)//判断质数
{
 for (int i = 3; i <= sqrt(n); i += 2)//偶数不是质数
  if (n%i == 0)return 0;
 return 1;
}
bool huiwen(int n)//判断回文数
{
 int i = n, m = 0;
 while (i > 0)
 {
  m = m * 10 + i % 10;
  i /= 10;
 }
 return m == n;
}
int main()
{
 int a, b;
 cin >> a >> b;
 if (b >10000000)b = 10000000;//偶数位数回文数(除11)必定不是质数(自行百度),所以可以只运行到10000000
 for (int i = a % 2 == 0 ? a + 1 : a; i <= b; i += 2)
 {
  if (i > 10000000)break;
  if (huiwen(i)&&prime(i))
    cout << i << endl;
 }
 return 0;
}

埃拉托斯特尼筛法:
在筛质数时,我们会发现,筛去2后,2的倍数4、6、8等一定不是素数;筛去3后,3的倍数6、9、12等一定不是倍数。简单模拟这个过程。时间复杂度是O(n*lglgn)。

#include
using namespace std;
const int SIZE = 10000005;
int prime[SIZE];//数组设为全局变量不容易爆栈
bool isHw(int n)//判断回文数
{
 int i = n, m = 0;
 while (i > 0)
 {
  m = m * 10 + i % 10;
  i /= 10;
 }
 return m == n;
}
int main()
{
 int a, b, i, j;
 cin >> a >> b;
 if (b >10000000)b = 10000000;
 for (int i = 0; i<SIZE; i++) prime[i] = 1;  //先把每个数都定义为素数
 for (int i = 2; i<SIZE; i++)//埃拉托斯特尼筛法
 {
  if (!prime[i]) continue;
  for (int j = i * 2; j<SIZE; j += i) prime[j] = 0;  //将i的倍数标记为合数
 }
 for (i = a % 2 == 0 ? a + 1 : a; i <= b; i += 2)
 {
  if (i > 10000000)break;
  if (isHw(i)&& prime[i])
    cout << i << endl;
 }
 return 0;
}

线性筛法(欧拉筛法):
原理:对于任意合数,必定可以有最小质因子乘以最大因子的分解方式。因此,对于每个合数,只要用最大因子筛一遍,枚举时只要枚举最小质因子即可。

你可能感兴趣的:(#,洛谷)