GHOJ 144 桐桐的发现

题目描述

        桐桐发现一个有趣的现象:除2这个特别的素数外,所有的素数都可以分成两类:第一类是被4除余1的素数,如5,13,17,29,37,41;第二类是被4除余3的素数,如3,7,11,19,23,31。桐桐感到很奇怪的是:第一类素数都能表示成两个整数的平方和,第二类则不能。如:

        5=1×1+2×2

        13=2×2+3×3

        17=1×1+4×4

        29=2×2+5×5

        更有趣的是:上述有些等式右侧的数又恰恰是两个素数,如上面13和29两个数所在式子的等号右侧就是素数,桐桐把这样的素数取名为“奇妙素数”。即:如果一个素数F能够表示成两个素数的平方和形式F=X×X+Y×Y,其中X,Y都是素数,那么它就是奇妙素数。

        请你帮助桐桐把所有不大于N的奇妙素数打印出来。

 

输入输出格式

输入格式

        一行,一个整数N3N108(3≤N≤108)。

 

输出格式

        第一行到第N行,输出不大于N的所有奇妙素数。每行输出1个,并把平方和的形式输出:F=XX+YYF=X∗X+Y∗Y;

        第N+1行,输出不大于N的所有奇妙素数的总数。

 

输入输出样例

输入样例

30

输出样例

13=2*2+3*3

29=2*2+5*5

2

 

题解

        明显奇妙素数是奇数,奇数加偶数等于奇数,又因为奇数的平方是奇数,偶数的平方是偶数,而唯一的偶数素数就是2,所以奇妙素数为2*2与另一个质数平方的和。

#include<cstdio>
#include<cmath>

using namespace std;

int p[10005];
int a[10005],cnt;
int n,sn;
int ans;

int main()
{
    scanf("%d",&n);
    sn=sqrt(n);
    for(int i=2;i<=sn;i++)
    {
        if(!p[i])
        {
            a[++cnt]=i;
            for(int j=i+i;j<=sn;j+=i) p[j]=1;
        }
    }
    for(int i=2;i<=cnt;i++)
    {
        if(a[i]*a[i]+4>n) break;
        if(a[i]*a[i]+4<=sn)
        {
            if(!p[a[i]*a[i]+4])
            {
                ans++;
                printf("%d=2*2+%d*%d
",a[i]*a[i]+4,a[i],a[i]);
            }
        }
        else
        {
            int t=a[i]*a[i]+4;
            for(int j=1;j<=cnt;)
            {
                if(a[j]>t||j==cnt)
                {
                    t=0;
                    break;
                }
                if(t%a[j]) j++;
                else break;
            }
            if(!t)
            {
                ans++;
                printf("%d=2*2+%d*%d
",a[i]*a[i]+4,a[i],a[i]);
            }
        }
    }
    printf("%d",ans);
    
    return 0;
}
参考程序
原文地址:https://www.cnblogs.com/kcn999/p/10344686.html