现在的位置: 首页 > 综合 > 正文

HDU 1431 素数回文(回文数打表)

2018年04月04日 ⁄ 综合 ⁄ 共 1095字 ⁄ 字号 评论关闭

题目链接:Click here~~

题意:

中文题不解释。练习了下打回文数。挺有成就感的,分享下。

解题思路:

先观察,1-9 中有 9 个回文数,10-99中有 9 个回文数,100-999中有 9*10 个回文数,1000-9999中有 9*10 个回文数……

不难分析出,[1,n] 区间内,回文数个数的级别是 O( 10 ^ ( |d/2 |) ) 的( d = log10(n) )。于是此题区间中共有 O( 10 ^ 4 ) 的回文数。

可以枚举出所有的回文数,然后判断他们是不是素数,把所有回文素数存成一个表,查询时二分即可。

复杂度大概O(10^4 * log(n) + log(10^4) * Q)。

#include <vector>
#include <stdio.h>
#include <algorithm>

using namespace std;

vector<int> ans;

bool is_prime(int x)
{
    for(int i=2;i*i<=x;i++)
        if(x%i == 0)
            return false;
    return true;
}

int reverse(int n)
{
    int res = 0;
    while(n)
    {
        int d = n % 10;
        res = res*10 + d;
        n /= 10;
    }
    return res;
}

void get_table()
{
    ans.push_back(5);
    ans.push_back(7);
    for(int l=1,base=1;l<=4;l++,base*=10)
    {
        for(int i=base;i<base*10;i++)
        {
            int pre_half = i * base * 10;
            int rev_half = reverse(i);
            int num = pre_half + rev_half;
            if(is_prime(num))
                ans.push_back(num);
            if(l == 4)
                continue;
            for(int mid=0;mid<10;mid++)
            {
                num = pre_half * 10 + mid * base * 10 + rev_half;
                if(is_prime(num))
                    ans.push_back(num);
            }
        }
    }
    sort(ans.begin(),ans.end());
}

int main()
{
    get_table();
    int a,b;
    while(~scanf("%d%d",&a,&b))
    {
        vector<int>::iterator l , r , it;
        l = lower_bound(ans.begin(),ans.end(),a);
        r = upper_bound(ans.begin(),ans.end(),b);
        for(it=l;it!=r;it++)
            printf("%d\n",*it);
        puts("");
    }
    return 0;
}

抱歉!评论已关闭.