NOI-OJ 1.13 ID:23 區間內的真素數


整體思路

  • 這里需要大量使用素數,必須能夠想到只求出M到N之間的素數是不夠的,因為M到N之間數字的反序有可能是大於M或小於N的數字,例如M=2,N=20,那么19的反序91大於20,所以使用埃拉拖色尼算法計算素數表的時候要讓范圍盡可能大,根據題目要求,設計為1~100000。

  • 本題也可以嘗試不使用阿拉托色尼算法,對M和N之間的每一個數及其反序進行素數判斷。

  • 本題的難點是求反序,方法較多,例程中提供兩種技巧供參考:

例程

#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
bool ss[100001];            //素數表
int  count;                 //計數器

void altsn(int N){          //埃拉拖色尼算法
    ss[0]=1;
    ss[1]=1;
    int p=2;
    while(p<=sqrt(N))
        if(ss[p]) p++;
        else{
            int times=2;
            while(p*times<=N)   { ss[p*times]=1; times++;}
            p++;
        }
}

bool isP(int n){            //素數判斷函數
    if(!ss[n])  return true;
    return false;
}

int rev(int n){                         //反序方法1
    char s1[10],s2[10];
    int len, reverse;
    sprintf(s1, "%d", n);               //sprintf輸出到數組s1
    len=strlen(s1);                     //反序復制到s2
    for(int i=0; i<len; i++)    s2[len-1-i]=s1[i];
    s2[len]='\0';                       //將s2補全為字符串
    sscanf(s2, "%d", &reverse);         //使用sscanf從s2中提取一個int
    return reverse;
}

int rev2(int n){                        //反序方法2
    int weishu=0;                       //n的位數
    int reverse=0;
    int t=n;
    while(t){                           //計算n的位數
        weishu++;
        t/=10;
    }
    t=n;
    while(t){                           //循環計算反序數值reverse
        reverse+=(t%10)*pow(10, --weishu);
        t/=10;
    }
    return reverse;
}

int main(){
    int M, N;
    cin>>M>>N;
    altsn(100000);
    for(int i=M; i<=N; i++)
        if(isP(i) && isP(rev(i))){      //如果i和i的反序都是素數
            count++;
            if(count==1)                //第一次輸出只輸出數字
                printf("%d", i);
            else                        //以后每次先輸出逗號,再輸出數字
                printf(",%d", i);
        }
    if(!count)  printf("No");
    return 0;
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com