---恢复内容开始---
#include <iostream> #include <cmath> #include <string> #include <vector> using namespace std; #define maxn 10000 int mark,cnt; int su[maxn]; int find(int su[],int s,int n){ for(int i=0;i<n;i++){ if(su[i]==s) return 1; } return 0; } void getsu(){ cnt=0; for(int i=2;i<maxn;i++){ mark=1; for(int l=2;l<sqrt(i);l++) if(i%l==0) {mark=0;break;} if(mark==1) su[cnt++]=i; } } int main(){ getsu(); freopen("UVa_in.txt","r",stdin); // freopen("UVa_out.txt","w",stdout); // cout<<cnt; // cout<<su[0]<<' '<<su[1]<<' '<<su[2]<<' '<<su[3]<<' '<<su[4]; int te,ans; while(cin>>te && te!=0){ ans=0; for(int i=0;i<cnt/2;i++){ if(su[i]<(te+1)/2){ if(find(su,te-su[i],cnt)) ans++; } } printf("%d ",ans); } return 0; }
这是我初始写的代码,先将10000以内的质数保存在数组,然后后面的查找就可以用二分法(虽然我没用)并且将一个内部循环的次数由n的一半,变成了n以内素数的个数的一半。听起来很完美,但是它运行不起来,应该是某些地方弄错了边界条件
我仿照网上的写法又写了一遍,还是WA,原因只是高亮区域少了一个等号,这提示我,对于边界情况一定要严谨,不能模糊
#include <iostream> #include <cmath> #include <string> using namespace std; int is_p(int n){ int k=sqrt(n); for(int i=2;i<k;i++) if(n%i==0) return 0; return 1; } int main(){ freopen("UVa_in.txt","r",stdin); int n,ans,i; while(scanf("%d",&n)==1 && n){ ans=0; for(i=3;i<n/2;i++) if(is_p(i) && is_p(n-i)) ans++; printf("%d ",ans); } return 0; }
---恢复内容结束---
#include <iostream> #include <cmath> #include <string> #include <vector> using namespace std; #define maxn 10000 int mark,cnt; int su[maxn]; int find(int su[],int s,int n){ for(int i=0;i<n;i++){ if(su[i]==s) return 1; } return 0; } void getsu(){ cnt=0; for(int i=2;i<maxn;i++){ mark=1; for(int l=2;l<sqrt(i);l++) if(i%l==0) {mark=0;break;} if(mark==1) su[cnt++]=i; } } int main(){ getsu(); freopen("UVa_in.txt","r",stdin); // freopen("UVa_out.txt","w",stdout); // cout<<cnt; // cout<<su[0]<<' '<<su[1]<<' '<<su[2]<<' '<<su[3]<<' '<<su[4]; int te,ans; while(cin>>te && te!=0){ ans=0; for(int i=0;i<cnt/2;i++){ if(su[i]<(te+1)/2){ if(find(su,te-su[i],cnt)) ans++; } } printf("%d ",ans); } return 0; }
这是我初始写的代码,先将10000以内的质数保存在数组,然后后面的查找就可以用二分法(虽然我没用)并且将一个内部循环的次数由n的一半,变成了n以内素数的个数的一半。听起来很完美,但是它运行不起来,应该是某些地方弄错了边界条件
我仿照网上的写法又写了一遍,还是WA,原因只是高亮区域少了一个等号,这提示我,对于边界情况一定要严谨,不能模糊
#include <iostream> #include <cmath> #include <string> using namespace std; int is_p(int n){ int k=sqrt(n); for(int i=2;i<k;i++) if(n%i==0) return 0; return 1; } int main(){ freopen("UVa_in.txt","r",stdin); int n,ans,i; while(scanf("%d",&n)==1 && n){ ans=0; for(i=3;i<n/2;i++) if(is_p(i) && is_p(n-i)) ans++; printf("%d ",ans); } return 0; }
上面骚粉高亮处部分是错误的,判断10000以为的偶数,有几种作为两个10000以内素数之和的情况,我们可以只判断处理第一个大于5000的质数之前的质数即可。可是,大于5000是第几个呢?我的方法直接处理判断第cnt/2个素数以前的素数(cnt为素数个数),可是问题就出在这里,谁告诉你,第cnt/2个素数正好是5000左右呢,根据经验,应该是0-5000以为素数多一点,所以这里把判断条件改为cnt,直接ac。
代码:
#include <iostream> #include <cmath> #include <string> #include <vector> using namespace std; #define maxn 10000 int mark,cnt; int su[maxn]; int find(int su[],int s){ //查找函数没问题 for(int i=0;i<cnt;i++) if(su[i]==s) return 1; return 0; } void getsu(){ //得到的素数表是没问题的 cnt=0;int mark; for(int i=2;i<maxn;i++){ mark=1; for(int l=2;l<=sqrt(i);l++) if(i%l==0) {mark=0;break;} if(mark==1) su[cnt++]=i; } } int main(){ getsu(); freopen("UVa_in.txt","r",stdin); // freopen("UVa_out.txt","w",stdout); // cout<<cnt; // cout<<su[0]<<' '<<su[1]<<' '<<su[2]<<' '<<su[3]<<' '<<su[4]; int te,ans; while(scanf("%d",&te) && te){ ans=0; for(int i=0;i<cnt;i++){ if(su[i]<te/2){ if(find(su,te-su[i])) ans++; } } printf("%d ",ans); } return 0; }
我的算法在n特别大,处理数据特别多的时候好处才能显示出来。