【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()函数 可以将字符串转为整数

原文地址:https://www.cnblogs.com/dplearning/p/3729515.html