<OJ_Sicily>Prime Palindromes

40 篇文章 0 订阅

Description

The number 151 is a prime palindrome because it is both a prime number and a palindrome (it is the same number when read forward as backward). Write a program that finds all prime palindromes in the range of two supplied numbers a and b (5 <= a < b <= 100,000,000); both a and b are considered to be within the range .

Input

There are multiple test cases.

Each case contains two integers, a and b.

a=b=0 indicates the end of input.

Output

For each test case, output the list of palindromic primes in numerical order, one per line.

题目解释:这道题主要是求解为质数的回文数

解题思路:在这里利用回文数的特点进行求解,也就是列举全部的回文数,然后判断其是否为质数,质数的判断是使用开根号方法缩小范围。

(1)4,6,8位的回文数没有质数。

对于4位回文数,有abba形式,那么abba = 1001*a + 110*b, 而1001*a + 110*b 肯定是可以被11整除的。同理对于6,8位回文数也肯定是可以被11整除,因此不存在4,6,8位回文数为质数

(2)关于回文数规律

比如5位回文数,其形式为ABCBA, 那么只需要3个for循环便可得到全部回文数,第一个for循环是A从1~9(其实A不能是偶数),第二个for循环是B从0~9,同理第三个for循环是从0~9.因此可以表示完全部的回文数,回文数为10001*A + 1010*B + 100*C

同理可以推出其他的回文数

#include<iostream>
#include <algorithm>
#include <math.h>
using namespace std;
int a, b;
bool isPrime(int k){
    double m = sqrt(k);
    for (int i = 2; i <= m; i++) {
        if (k % i == 0) {
            return false;
        }
    }
    return true;
}
int main(){
    while (cin >> a >> b) {
        if (a == 0 && b == 0) break;
        int tmp;

        for (int i = 2; i <= 7; i ++) {   // 1位回文数
            tmp = i;
            if (i >= a && i <= b && isPrime(tmp)) {
                cout << tmp << endl;
            }
        }
        for (int i = 1; i <= 9; i+= 2) {  // 两位回文数
            tmp = 11* i;
            if (tmp >= a && tmp <= b && isPrime(tmp)) {
                cout << tmp << endl;
            }
        }
        for (int i = 1; i <= 9; i+= 2){     // 3 位数回文
            for (int j = 0; j <= 9; j ++) {
                tmp = i * 101 + j * 10;
                if (tmp >= a && tmp <= b && isPrime(tmp)) {
                    cout << tmp << endl;
                }
            }
        }
        for (int i = 1; i <= 9; i +=2) {    // 5位数回文
            for (int j = 0; j <= 9; j ++) {
                for (int k = 0; k <= 9; k ++) {
                    tmp = 10001 * i + 1010 * j + 100 * k;
                    if (tmp >= a && tmp <= b && isPrime(tmp)) {
                        cout << tmp << endl;
                    }
                }
                
            }
        }
        for (int i = 1; i <= 9; i += 2) {    // 7位数回文
            for (int j = 0; j <= 9; j ++) {
                for (int k = 0; k <= 9; k ++) {
                    for (int l = 0; l <= 9; l++) {
                        tmp = 1000001 * i + 100010 * j + 10100 * k + 1000 * l;
                        if (tmp >= a && tmp <= b && isPrime(tmp)) {
                            cout << tmp << endl;
                        }
                    }
                }
            }
        }

        for (int i = 1; i <= 9; i ++) {    //9位数回文
            for (int j = 0; j <= 9; j ++) {
                for (int k = 0; k <= 9; k ++) {
                    for (int l = 0; l <= 9; l++) {
                        for (int m = 0; m <= 9; m ++) {
                            tmp = 100000001 * i + 10000010 * j + 1000100 * k + 101000 * l + 10000 * m;
                            if (tmp >= a && tmp <= b && isPrime(tmp)) {
                                cout << tmp << endl;
                            }
                        }
                        
                        
                    }
                }
            }
        }
        
    }
    return 0;
}


如果要在不使用 `#include <unordered_set>` 的情况下实现类似功能,我们可以使用数组或列表来模拟邻接表,并使用位运算来标记已访问的箱子。这里是一个基于数组的解决方案: ```cpp #include <iostream> #include <vector> using namespace std; const int MAX_N = 100; // 假设箱子不超过100个 // 用一个布尔数组表示箱子是否被访问过,初始化全为false bool visited[MAX_N + 1]; // 定义邻接矩阵,使用二维数组表示箱子之间的钥匙关系 vector<vector<int>> graph(MAX_N + 1, vector<int>(MAX_N + 1)); void findUnlockable(int n, vector<int>& graph, vector<int>& result) { // 初始化遍历标志 for (int i = 0; i <= n; ++i) { visited[i] = false; } // 从第一个箱子开始,进行深度优先搜索 dfs(1, graph, result); } void dfs(int node, vector<int>& graph, vector<int>& result) { // 标记当前箱子已访问 visited[node] = true; // 添加当前箱子到结果中 result.push_back(node); // 遍历邻居节点 for (int nei : graph[node]) { // 如果邻居未被访问,则递归继续搜索 if (!visited[nei]) { dfs(nei, graph, result); } } } int main() { int n, m; cin >> n >> m; // 读取钥匙隐藏关系并更新邻接矩阵 for (int i = 0; i < m; ++i) { int u, v; cin >> u >> v; graph[u][v] = 1; // 表示箱子u的钥匙在箱子v中,这里的1只是一个标记 } vector<int> unlockable; // 用于存储结果 findUnlockable(n, graph, unlockable); // 输出结果 for (int box : unlockable) { cout << box << " "; } cout << endl; return 0; } ``` 请注意,这种方法仅适用于箱子数量较小的情况,因为数组大小是固定的,不适合大规模的数据。如果输入规模未知或者可能会很大,建议还是使用 `unordered_set` 或其他哈希集合来优化查找效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值