zoukankan      html  css  js  c++  java
  • P1217 [USACO1.5]回文质数 Prime Palindromes(技巧+暴力枚举+线性筛)

    技巧:就是偶数位的回文数字一定不是质数---------证明:奇数位之和sum1==偶数位之和sum2的数字可以被11整除。(11除外,这是一个坑点)

       最高位,最低位必须是 1, 3, 7, 9

    暴力枚举:也就是说,直接枚举奇数位(1,3,5,7)就可以了。至于回文嘛,除去最高位和最低位,也最多是枚举3位数字,时间复杂度在10^3.不管怎么说还是暴力的起的。

    线性筛:就是用于判断最后枚举的数字是不是质数的,注意,还是要把质数的范围取大一点。根据质数在后面越来越少的概率图,大家,可以随便定个范围。

        最开始,是筛的1000以内的质数,但是,错了很多,所以筛了10000以内的就过了。

    ac代码:

    #include<iostream>
    using namespace std;
    const int N = 1e4;
    int prime[N], sum, r, l;
    bool vis[N];
    bool is_prime[N];
    int a[] = { 1, 3, 7, 9 };
    int kk[] = { 5, 7 ,11};
    int Prime(int n = N){
        int cnt = 0;
        for (int i = 2; i <= n; ++i)
        {
            if (!vis[i]){
                prime[cnt++] = i;
                is_prime[i] = 1;
            }
            for (int j = 0; j < cnt&&i*prime[j] <= n; ++j)
            {
                vis[i*prime[j]] = 1;
                if (i%prime[j] == 0)break;
            }
        }
        return cnt;
    }
    
    bool f(int x){
        if (x < N)return is_prime[x];
        else{
            for (int i = 0; i < sum; ++i){
                if (x%prime[i] == 0)return 0;
            }
        }
        return 1;
    }
    
    void DFS(){
        int num;
        for (int i = 0; i <= 2;++i)
        if (kk[i] >= l&&kk[i] <= r)cout << kk[i] << endl;
        if (r / 100){
            for (int i = 0; i <= 3; ++i){
                for (int j = 0; j <= 9; ++j){
                    num = a[i] * 100 + j * 10 + a[i];
                    if (num>=l&&num<=r&&f(num))cout << num << endl;
                }
            }
        }
        if (r / 10000){
            for (int i = 0; i <= 3; ++i){
                for (int a1 = 0; a1 <= 9;++a1)
                for (int a2 = 0; a2 <= 9; ++a2){
                    num = a[i] * 10000 + a1 * 1000 + a2 * 100 + a1 * 10 + a[i];
                    if (num >= l&&num <= r&&f(num))cout << num << endl;
                }
            }
        }
        if (r / 1000000){
            for (int i = 0; i <= 3; ++i){
                for (int a1 = 0; a1 <= 9; ++a1)
                for (int a2 = 0; a2 <= 9; ++a2)
                for (int a3 = 0; a3 <= 9;++a3){
                    num = a[i] * 1000000 + a1 * 100000 + a2 * 10000+a3*1000+a2*100 + a1 * 10 + a[i];
                    if (num >= l&&num <= r&&f(num))cout << num << endl;
                }
            }
        }
    }
    
    int main(){
        sum = Prime();
        cin >> l >> r;
        DFS();
    }
  • 相关阅读:
    Cpp Chapter 12: Classes and Dynamic Memory Allocation Part1
    Cpp Chapter 11: Working with Classes Part2
    Cpp Chapter 11: Working with Classes Part1
    Cpp Chapter 10: Objects and Classes Part2
    摄影技术学习
    安装texlive2017(latex的编译软件)
    文献管理工具的使用(Mendeley和Endnote)
    函数的级数展开和渐近展开
    常用英语语法小结
    常微分方程
  • 原文地址:https://www.cnblogs.com/ALINGMAOMAO/p/10657963.html
Copyright © 2011-2022 走看看