【埃氏筛+暴力打表】 HRBUST 2323 Emirp

本文介绍了一种特殊类型的质数——Emirp数,并提供了一个算法解决方案。Emirp数是指一个质数,其数字反转后仍为质数但不同于原数。文章通过埃氏筛法筛选质数,并采用二分查找验证反转后的数字是否为质数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Emirp

Time Limit: 5000 MS Memory Limit: 100000 K

Description

An emirp (prime spelled backwards) is a prime number that results in a different prime when its decimal digits are reversed.

The first five emirps are 13, 17, 31, 37, 71

Now Kim want to know the kth emirp. Help him.

Input

The first line is an integer T, describes the number of tests. Then T tests.

In each test, one line an integer k.

Output

For each test, output the kth emirp.

Sample Input

3
1
2
3

Sample Output

13
17
31

Hint

T<=10000

k<=1000

Source

“科林明伦杯”哈尔滨理工大学第六届程序设计团队赛

题目大意

给你前5个数字,通过观察找到第k个满足题目条件的数字。

解题思路

不难发现给出的前5个数有以下两个特征
1、这个数是质数。
2、这个数的反转数还是质数。
3、这个数的反转数不能是自身。

然后不难想到使用埃氏筛+二分查找。
先预处理一下:
埃氏筛先找到一定数量的质数。
然后从第一个质数开始将其反转。
反转后的新数用二分查找一下看看在已知的质数当中它是不是质数
如果是的话存入一个准备好的数组当中。
根据题目要求的数据范围我们只需要处理出前1000个符合题目的数字即可。
然后它要求第几个,我们输出就好。

上面这一段话精简一下就是四个字:暴力打表。

AC代码

#include<bits/stdc++.h>
using namespace std;

bool is_prime[1000000];
int prime[1000000];
int ans[1006];

bool half(int ri,int aim)///二分查找
{
    int l = 0,r = ri - 1;
    int mid;
    while(l<=r)
    {
        mid = (l+r)/2;
        if(prime[mid] == aim)
        {
            return true;
        }
        if(aim < prime[mid]) r = mid - 1;
        else l = mid +1;
    }
    return false;
}

void init(void)
{
    /*埃氏筛*/
    int p = 0;
    fill(is_prime,is_prime+1000000,true);
    is_prime[0] = is_prime[1] = false;
    for(int i = 1 ; i < 1000000 ; i++)
    {
        if(is_prime[i] == true)
        {
            prime[p++] = i;
            for(int j = i ; j <=1000000 ; j+=i) is_prime[j] = false;
        }
    }
    /*找到符合条件的数字*/
    int flag = 0;
    for(int i = 5 ; i < p && flag <1006; i++)
    {
        int fanzhuan = 0;
        int caozuo = prime[i];
        while(caozuo)///反转数字
        {
            int temp = caozuo%10;
            caozuo/=10;
            fanzhuan = (fanzhuan * 10) + temp;
        }
        if(fanzhuan!=prime[i]&&half(p,fanzhuan)==true)///是质数而且反转后不是自身。
        {
            ans[flag++] = prime[i];
        }
    }

}


void solve(void)
{
    int t;
    cin>>t;
    init();
    while(t--)
    {
        int n;
        cin>>n;
        cout<<ans[n-1]<<endl;
    }
}

int main(void)
{
    solve();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两米长弦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值