题目
数学问题(math.cpp,1s,128MB)
【问题描述】:
在一个渺无人烟的荒岛上待了 xx 年之后,小 Y 基本上啥都不会了。所以当小 Z 告诉他任何一个大于等于 4 的偶数都能表示成两个质数的和这个事实的 时候,小 Y 根本不相信!小 Y 现在想找出一些反例,你能帮助他吗
【输入文件】:
输入文件 math.in 中仅包含一个整数 n。
【输出文件】:
输出文件为 math.out。如果 n 不能表示成两个质数的和,则输出“NO WAY!”;
否则输出一种方案,如果有多种可行方案,输出两个质数差最大的那一种。
【输入输出样例】:
样例 1:
math.in
10
math.out
10=3+7
样例 2:
math.in
11
math.out
NO WAY!
【数据规模】:
100%的数据中,3≤n≤1,000,000。
考试得分: 100
主要算法 : 质数(欧拉素数筛)
应试策略:
- 欧拉素数筛,将1-n的素数筛处来
- 一一枚举第一个质数,再O(1)判断n-(这个质数)是不是质数
代码
#include<map> #include<math.h> #include<stdio.h> #include<stdlib.h> #define FORa(i,s,e) for(int i=s;i<=e;i++) #define FORs(i,s,e) for(int i=s;i>=e;i--) #define gc pa==pb&&(pb=(pa=buf)+fread(buf,1,10000,stdin),pa==pb)?EOF:*pa++ #define File(name) freopen(name".in","r",stdin),freopen(name".out","w",stdout) using namespace std; static char buf[10000],*pa=buf,*pb=buf; inline int read(); const int N=1000000; map<int,bool> mp; int n,cnt,prime[N+1],v[N+1]; void Oulashai() { FORa(i,2,n) { if(!v[i]) v[i]=i,prime[++cnt]=i,mp[i]=1; FORa(j,1,cnt) { if(prime[j]>v[i]||prime[j]*i>n) break; v[prime[j]*i]=prime[j]; } } } void Solve() { FORa(i,1,n) { if(mp[i]&&mp[n-i]) { printf("%d=%d+%d",n,i,n-i); exit(0); } } printf("NO WAY!"); } int main() { File("math"); n=read(); Oulashai(); Solve(); return 0; } inline int read() { register int x(0);register int f(1);register char c(gc); while(c<'0'||c>'9') f=c=='-'?-1:1,c=gc; while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=gc; return x*f; }
非完美算法:
照搬应试策略
正解:
照搬应试策略
总结:
欧拉素数筛