洛谷P1217 回文质数 Prime Palindromes

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

写一个程序来找出范围[a,b](5 <= a < b <= 100,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的回文数:

for (d1 = 1; d1 <= 9; d1+=2) { // 只有奇数才会是素数

 for (d2 = 0; d2 <= 9; d2++) {
     for (d3 = 0; d3 <= 9; d3++) {
       palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;//(处理回文数...)
     }
 }
}

可以证明大于两位(digits)的回文数不存在质数,因为它们都是11的倍数。
洛谷P1217 回文质数 Prime Palindromes_第1张图片

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

bool IsPrime(int X)//判断一个数是不是质数
{
    for (int i = 2; i < sqrt(X) + 1; i++)
    {
        if (X%i == 0)
            return 0;
    }
    return 1;
}

void solve(int& a, int& b, int N, int half, int K, vector<int>& vec)
{
    //K表示当前正整数有几位数字
    if (K == half)
    {
        for (int i = N/2 - 1; i >= 0; i--)//补全另一半(digits)
        {
            vec.push_back(vec[i]);
        }
        int temp = 1, sum=0;
        for (int i = 0; i < N; i++)//计算这个数字(number)的值
        {
            sum += vec[i] * temp;
            temp = temp * 10;
        }
        if (IsPrime(sum) && sum >= a && sum <= b)//判断其是否满足条件
        {
            cout << sum << endl;
        }
        /*for (int i = 0; i < N - half; i++)  
            vec.pop_back();*/
        vec.erase(vec.end() - N + half, vec.end());//将刚刚补的数字(digits)删除
    }
    else if (K == 0)
    {
        for (int i = 1; i <= 9; i+=2)//第一位数字只能是奇数
        {
            vec.push_back(i);//将第一位数字(digit)放入容器中
            solve(a, b, N, half, K + 1, vec);
            vec.pop_back();//将第一位数字从容器中取出,从而放入下一位数字(digit)
        }
    }
    else if (K < half)
    {
        for (int i = 0; i <= 9; i++)
        {
            vec.push_back(i);//将一位数字(digit)放入容器中
            solve(a, b, N, half, K + 1, vec);

            //取出容器中最后一个数字(digit),从而存放下一个数字(digit)
            vec.pop_back();
        }
    }

}

int GetDigits(int X)//返回一个正整数有几位数字
{
    int ret = 0;
    while (X > 0)
    {
        ret++;
        X /= 10;
    }
    return ret;
}

int main()
{
    int a, b;
    cin >> a >> b;
    vector<int> vec;
    int a1 = GetDigits(a), b1 = GetDigits(b);
    int half;

    for (int i = a1; i <= b1&&i<9; i++)
    {
        if (i & 1)//如果i为奇数,则half为i向上取整
            half = ((i + 1) / 2);
        else if(!(i&1)&&i>2)//如果i为偶数且大于2,则跳过
            continue;
        solve(a, b, i, half, 0, vec);//进入递归
    }
    return 0;
}

你可能感兴趣的:(1)