USACO 回文质数

题目:回文质数

题目描述

给定a,b(1<a,b<10,000,000,000)请求出所有在这两个数范围内,既是回文又是质数的数字。

题目思路

因为范围过于大,如果遍历范围内的每一个数字,判定是否为质数?是否为回文?复杂度过高。
问题是缩小范围
首先,位数是偶数的回文数字必是11的倍数(除11本身)(例如 2112=11*192),所以1000万到1亿之间不可能存在回文质数,将范围缩小至1000万。

很多选择枚举范围的做法,这里写一下自己想的生成回文,比如数字b翻转过来是d,那么可以生成三类回文:b本身bdb?d(?是0~9),例如 (b=123 123、123321、1230321……1239321)。
在回文集合中判定每一个回文数是否为质数,最后排序及去重输出。

#include<bits/stdc++.h>
using namespace std;
#define Max 3162
int n,m,k,i,j,cnt,a,b;
int ans[100010],tmp[12];
bool check(int x){//判断是否为质数
    if(x<a||x>b) return false;
    for(int i=2;i<=sqrt(x);i++){
        if(x%i==0) return false;
    }
    return true;
}
bool checkP(int x){//检查是否回文
    int t[20],tnum=0;//t为保存数字的数组,tnum为下标
	while(x){
		t[++tnum]=x%10;
		x/=10;
	}
	for(int i=1;i<=tnum/2;i++){
		if(t[i]!=t[tnum-i+1]) return 0;
	}
	return 1;
}
int compent(int x){
    int t=x;
    tmp[1]=x;
    while(t){
        tmp[1]=tmp[1]*10+t%10;
        t/=10;
    }
    for(int i=0;i<10;i++){
        t=x;
        tmp[i+2]=x*10+i;
        while(t){
            tmp[i+2]=tmp[i+2]*10+t%10;
            t/=10;
        }
    }
}

int main()
{
    cin>>a>>b;
    for(i=1;i<3162;i++){//i ii i?i
        if(checkP(i)) tmp[0]=i;
        else tmp[0]=4;
        compent(i);//形成 ii 及 i?i
        for(j=0;j<12;j++){
            if(check(tmp[j])) ans[++cnt]=tmp[j];
        }
    }
    sort(ans+1,ans+1+cnt);
    for(i=1;i<=cnt;i++){
        if(ans[i]!=ans[i-1]) cout<<ans[i]<<endl;
    }
}
上一篇:2020/2/22-2


下一篇:Windows协议 LDAP篇 - 组&OU