题目描述
桐桐发现一个有趣的现象:除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的奇妙素数打印出来。
输入输出格式
输入格式
一行,一个整数N(3≤N≤108)(3≤N≤108)。
输出格式
第一行到第N行,输出不大于N的所有奇妙素数。每行输出1个,并把平方和的形式输出:F=X∗X+Y∗YF=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; }