• 一本通 P1800 质数


    一本通原题

    这题我们可以使用哥德巴赫猜想,虽然没被完全证明,但是(frac{6000* 6001}{2})的范围我们完全能撑得住

    我们可以记数的总和(sum=sum_{i=1}^{n}i=frac{n* (n+1)}{2})

    我们可以讨论四种情况:
    (sumin P)是,显然(cnt=1)
    (sum-2 in P),显然(cnt=2)
    (sum equiv 0(mod 2))时,显然(cnt=2)
    (sum-3 in P)(sum-3 eq 2)时,显然(cnt=3)

    如果都不满足或(nleq1)显然输出(-1)

    至于选数,我们可以使用贪心

    #include<stdio.h>
    #include<ctype.h>
    #include<algorithm>
    #define re register
    using namespace std;
    namespace IO
    {
    	template<typename T>
    	inline void read(T & x)
    	{
    		x=0;
    		bool b=false;
    		char ch=getchar();
    		while(!isdigit(ch)&&ch^'-')
    			ch=getchar();
    		if(ch=='-')
    		{
    			b=true;
    			ch=getchar();
    		}
    		while(isdigit(ch))
    		{
    			x=(x<<1)+(x<<3)+(ch^'0');
    			ch=getchar();
    		}
    		if(b)
    			x=~x+1;
    		return;
    	}
    	char Out[1<<30],*fe=Out,ch[25];
    	int num=0;
    	template<typename T>
    	inline void write(T x,char s)
    	{
    		if(!x)
    			*fe++='0';
    		if(x<0)
    		{
    			*fe++='-';
    			x=-x;
    		}
    		while(x)
    		{
    			ch[++num]=x%10+'0';
    			x/=10;
    		}
    		while(num)
    			*fe++=ch[num--];
    		*fe++=s;
    	}
    	inline void flush()
    	{
    		fwrite(Out,1,fe-Out,stdout);
    		fe=Out;
    	}
    }
    using IO::read;
    using IO::write;
    const int N=6010*6010;
    int n,m,sum,cnt=-1,ans[6010],prime[N];
    int vis[N];
    bool v[N];
    inline void solve(int s)
    {
    	int x=s;
    	while(s&&x)
    	{
    		if(ans[x]==1)
    		{
    			ans[x]=2;
    			s-=x;
    		}
    		x=x>s?s:x-1;
    	}
    	return;
    }
    inline void primes(int n)
    {
    	m=0;
    	for(re int i=2; i<=n; i++)
    	{
    		if(vis[i]==0)
    		{
    			vis[i]=i;
    			v[i]=true;
    			prime[++m]=i;
    		}
    		for(re int j=1; j<=m; j++)
    		{
    			if(prime[j]>vis[i]||prime[j]>n/i)
    				break;
    			vis[i*prime[j]]=prime[j];
    		}
    	}
    }
    int main()
    {
    	read(n);
    	if(n<=1)
    	{
    		write(-1,'
    ');
    		IO::flush();
    		return 0;
    	}
    	sum=n*(n+1)>>1;
    	fill(ans+1,ans+1+n,1);
    	primes(sum);
    	if(v[sum])
    		cnt=1;
    	else
    	{
    		if(v[sum-2])
    		{
    			ans[2]=2;
    			cnt=2;
    			solve(sum-2);
    		}
    		else if(sum%2==0)
    		{
    			for(re int i=1; i<=m; i++)
    				if(v[sum-prime[i]])
    				{
    					solve(prime[i]);
    					cnt=2;
    					break;
    				}
    		}
    		else
    		{
    			ans[3]=3;
    			sum-=3;
    			for(re int i=1; i<=m; i++)
    				if(v[sum-prime[i]])
    				{
    					solve(prime[i]);
    					cnt=3;
    					break;
    				}
    		}
    	}
    	write(cnt,'
    ');
    	if(cnt>0)
    	{
    		for(re int i=1; i<=n; i++)
    			write(ans[i],' ');
    	}
    	IO::flush();
    	return 0;
    }
    
    
  • 相关阅读:
    20180925-3 效能分析
    20180925-7 规格说明书-吉林市2日游
    20180918博客作业
    第二周例行报告
    2018091-2博客作业
    容器(list集合)
    给应届生们的建议(一定要看哦)!
    MySQL 和 JDBC(Java数据库连接)
    Oracle常用数据库对象(片段)
    7353. 【2021.11.06NOIP提高A组模拟】qaq (qaq)
  • 原文地址:https://www.cnblogs.com/wangjunrui/p/11923537.html
Copyright © 2020-2023  润新知