分享一下我的做法

P1579 哥德巴赫猜想(升级版)

draymonder @ 2017-08-25 21:17:23

之前没发过贴 也不知道怎么发代码

我的思路是线性筛然后判断题意范围内有2262个素数

然后暴力枚举 prime[i],prime[j] 只需要判断 n-prime[i]-prime[j]是不是素数就行

#include<bits/stdc++.h>
using namespace std;
const int maxn = 20100;
int n,cnt;//表示maxn以内的素数个数
bool vis[maxn];
int prime[maxn];
void f()//线性筛 打表
{
    memset(vis,0,sizeof(vis));
    memset(prime,0,sizeof(prime));
    vis[0] = vis[1] = 1;
    cnt = 0;
    for(int i=2;i<=maxn;i++)
    {
        if(!vis[i])
            prime[cnt++]=i;
        for(int j=0;j<cnt && i*prime[j]<=maxn;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)
                break;
        }
    }
}
void solve()
{
    for(int i=0;i<cnt;i++)
    {
        for(int j=i;j<cnt&& prime[j]+prime[i]<n;j++)
        {
            if(!vis[n-prime[i]-prime[j]]){
                cout<< prime[i]<<" "<<prime[j]<<" "<<n-prime[i]-prime[j]<<endl;
                return;
            }
        }
    }
}
int main ()
{
    //freopen("out.txt","w",stdout);
    cin >> n;
    f();//发现有2262个素数 可以n2处理
    solve();
    return 0;
}

by zhang9302002 @ 2017-08-30 19:51:49

这里其实可以由小到大枚举前两个素数,再算出第三个进行判断,时间复杂度O(n^2)。

代码如下::

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int p[5010],top=20000,cnt;
bool no[20010];
void Euler(){
    no[1]=true;
    for(int i=2;i<=top;i++){
        if(!no[i])
            p[cnt++]=i;
        for(int j=0;j<cnt&&i*p[j]<=top;j++){
            no[i*p[j]]=true;
            if(!i%p[j])break;
        }
    }
}
int main(){
    Euler(); 
    cin>>n;
    int j,k;
    for(j=0;j<cnt&&p[j]<=n-4;j++)
        for(k=j;k<cnt&&p[k]+p[j]<=n-2;k++)
            if(!no[n-p[j]-p[k]]){
                cout<<p[j]<<" "<<p[k]<<" "<<n-p[j]-p[k];
                return 0;
            }
    return 0;
}

|