【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\n", 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\n", pal);

                }



            }

            else

            {

                for(k = 0; k < lll; k++)

                {

                    pal = pal * 10 + num[k];

                }

                if(pal > b) return 0;

                if(isprime(pal))

                {

                    fprintf(out, "%d\n", 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()函数 可以将字符串转为整数

你可能感兴趣的:(USACO)