• 【USACO】pprime


    开始看第一眼题就觉得问题会在超时上,果然写了个小代码运行到test 9时超时了

    #include <stdio.h>
    #include <math.h>
    
    int isprime(int M)
    {
        int i;
        float N = M;
        for(i = 2; i <= sqrt(N); i++)
        {
            if(M % i == 0)
                return 0;
        }
        return 1;
    }
    
    int ispalindromes(int N)
    {
        char numc[9] = {0};
        int l;
        char *p, *q;
        for(l = 0; N != 0; l++)
        {
            numc[l] = N % 10 + '0';
            N = N / 10;
        }
        l--;
        for(p = numc, q = numc + l; p < q; p++, q--)
        {
            if(*p != *q)
                return 0;
        }
        return 1;
    }
    
    int main()
    {
        FILE *in, *out;
        in = fopen("pprime.in", "r");
        out = fopen("pprime.out", "w");
    
        int a, b;
        fscanf(in, "%d %d", &a, &b);
    
        int i, j;
        for(i = a; i <= b; i++)
        {
            if(ispalindromes(i) && isprime(i))
            {
                fprintf(out, "%d
    ", i);
            }
        }
    
        return 0;
    }

     ----------------------------------------------

    化简途径是直接生成回文 我的代码边界处理的有点乱 不过AC了 确实速度比一个个判断快很多 大概快个100倍吧

    每次回文生成的前半段都是 10 — 99  100 - 999 1000 - 9999 这样的情况,要分奇偶数处理

    #include <stdio.h>
    #include <math.h>
    
    int isprime(int M)
    {
        int i;
        float N = M;
        for(i = 2; i <= sqrt(N); i++)
        {
            if(M % i == 0)
                return 0;
        }
        return 1;
    }
    int main()
    {
        FILE *in, *out;
        in = fopen("pprime.in", "r");
        out = fopen("pprime.out", "w");
    
        int a, b;
        int i, j, k;
        int l, s;
        int bb, aa;
        fscanf(in, "%d %d", &a, &b);
    
        bb = b;
        aa = a;
    
        for(l = 0; bb != 0; l++)
        {
            bb = bb / 10;
        }
        for(s = 0; aa != 0; s++)
        {
            aa = aa / 10;
        }
        for(i = s; i <= l; i++)
        {
            int small, large; //回文产生中,不重复部分最大最小值
    
            int ll = i/2 + i % 2; //回文不重复长度
            if(i == s)  //最小边界
            {
                small = a;
                for(j = 0; j < i - ll; j++)
                {
                    small = small / 10;
                }
            }
            else
            {
                for(small = 1, j = 1; j < ll; j++)
                {
                    small = small * 10;
                }
            }
            for(large = 1, j = 1; j <= ll; j++)
            {
                large = large * 10;
            }
            large--;
    
            for(j = small; j <= large; j++)
            {
                int lll;
                int pal;
                int num[9] = {0};
                int jj = j;
                for(k = 0; jj != 0; k++)
                {
                    num[k] = jj % 10;
                    jj = jj / 10;
                }
                lll = k;
                pal = j;
                if(i % 2 == 1)
                {
                    for(k = 1; k < lll; k++)
                    {
                        pal = pal * 10 + num[k];
                    }
                    if(pal > b) return 0; //不能超过最大值
                    if(isprime(pal))
                    {
                        fprintf(out, "%d
    ", pal);
                    }
    
                }
                else
                {
                    for(k = 0; k < lll; k++)
                    {
                        pal = pal * 10 + num[k];
                    }
                    if(pal > b) return 0;
                    if(isprime(pal))
                    {
                        fprintf(out, "%d
    ", pal);
                    }
                }
            }
        }
    
        return 0;
    }

    看了下答案,思路差不多,但是比我的清楚很多。学习到的技巧:

    素数判断:

    int 
    isprime(long n)
    {
        long i;
    
        if(n == 2)   // 2单独处理
            return 1;
    
        if(n%2 == 0)
            return 0;
    
        for(i=3; i*i <= n; i+=2)  // i * i <= n 可以避免sqrt
            if(n%i == 0)
                    return 0;
    
        return 1;
    }

    atol()函数 可以将字符串转为整数

  • 相关阅读:
    java web项目防止多用户重复登录解决方案
    java提高篇(二一)-----ArrayList
    转:为什么需要htons(), ntohl(), ntohs(),htons() 函数
    转:对于linux下system()函数的深度理解(整理)
    转:sprintf与snprintf
    转: fscanf()函数详解
    转:fopen()函数
    转:struct sockaddr与struct sockaddr_in ,struct sockaddr_un的区别和联系
    转:BZERO()等的区别
    转:Linux内存管理之mmap详解
  • 原文地址:https://www.cnblogs.com/dplearning/p/3729515.html
Copyright © 2020-2023  润新知