杭二集训 质数
2018-01-15 14:42
281 查看
标签:哥德巴赫猜想
【题目描述】
将1~n分成尽可能少的集合,使得每个集合的元素和均为质数。
【输入数据】
一行一个正整数n。
【输出数据】
第一行一个正整数m表示最少集合数,第二行n个[1,m]中的整数,第i个整数表示i在第几个集合中。若有多种方案输出任意一种即可。若无解输出-1。
【样例输入】
8
【样例输出】
2
1 2 2 1 1 1 1 2
【数据范围】
对于30%的数据,n<=20。
对于100%的数据,n<=6000。
1. m为质数,那么直接输出1
2. m为合数且为偶数,根据哥德巴赫猜想:任何一个大于2的偶数都能表示为两个质数的和,输出2
3. m为合数且为奇数,如果m-2为质数的话,那么分为2和m-2两个质数,答案为2,
4. m为合数且为奇数,如果m-2不是质数的话,分为3和m-3,其中m-3确定为偶数,再次根据哥德巴赫猜想,可以将m-3再次划分为2组,所以答案为3
5. n==1或0,那么输出无解-1
题目
质数(prime)【题目描述】
将1~n分成尽可能少的集合,使得每个集合的元素和均为质数。
【输入数据】
一行一个正整数n。
【输出数据】
第一行一个正整数m表示最少集合数,第二行n个[1,m]中的整数,第i个整数表示i在第几个集合中。若有多种方案输出任意一种即可。若无解输出-1。
【样例输入】
8
【样例输出】
2
1 2 2 1 1 1 1 2
【数据范围】
对于30%的数据,n<=20。
对于100%的数据,n<=6000。
分析
分几种情况讨论:设m为∑i=1ni1. m为质数,那么直接输出1
2. m为合数且为偶数,根据哥德巴赫猜想:任何一个大于2的偶数都能表示为两个质数的和,输出2
3. m为合数且为奇数,如果m-2为质数的话,那么分为2和m-2两个质数,答案为2,
4. m为合数且为奇数,如果m-2不是质数的话,分为3和m-3,其中m-3确定为偶数,再次根据哥德巴赫猜想,可以将m-3再次划分为2组,所以答案为3
5. n==1或0,那么输出无解-1
code
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,a,b) for(int i=a;i>=b;i--) #define ll long long #define mem(x,num) memset(x,num,sizeof x) #define reg(x) for(int i=last[x];i;i=e[i].next) using namespace std; inline ll read() { ll f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=1e6+6; bool is_p 4000 rime[maxn]; int prime[maxn],cnt,n,vis[maxn]; ll s; void getprime(){ rep(i,2,maxn-6){ if(!is_prime[i])prime[++cnt]=i; rep(j,1,cnt){ if(prime[j]*i>maxn-6)break; is_prime[i*prime[j]]=1; if(i%prime[j]==0)break; } } } bool check(ll x){ rep(i,2,trunc(sqrt(x))+1) if(x%i==0)return 0; return 1; } int main() { getprime(); n=read(); if(n==0||n==1){cout<<"-1\n";return 0;} rep(i,1,n)s+=i; //cout<<s<<endl; if(check(s)){ cout<<'1'<<endl; rep(i,1,n)cout<<"1 ";cout<<endl; return 0; }else if(s%2==0){ rep(i,1,cnt) if(check(s-prime[i])){vis[prime[i]]=1;break;} cout<<'2'<<endl; rep(i,1,n)if(vis[i])cout<<"2 ";else cout<<"1 ";cout<<endl; return 0; }else if(check(s-2)){ cout<<'2'<<endl;vis[2]=1; rep(i,1,n)if(vis[i])cout<<"2 ";else cout<<"1 ";cout<<endl; return 0; }else { cout<<'3'<<endl;vis[3]=2; rep(i,1,cnt){ if(prime[i]==3)continue; if(check(s-3-prime[i])){vis[prime[i]]=1;break;} } rep(i,1,n)if(!vis[i])cout<<"3 ";else cout<<vis[i]<<' ';cout<<endl; return 0; } }
相关文章推荐
- 【2017省中集训DAY1T1】 小X的质数
- 杭二集训 电报
- 杭二集训 三明治
- 杭二集训 diyiti (CF GYM 101597A)
- 杭二集训 dierti (CF GYM 100016F)
- 杭二集训 函数
- 杭二集训 disanti (51Nod 1667 概率好题)
- 13暑假集训#4 总结
- 寒假集训Day 3 D题 Uva 1589 象棋
- 2013暑假集训B组训练赛第二场
- 5414. 【NOIP2017提高A组集训10.22】幸运值
- 13暑假集训#8 总结
- 质数筛选(欧拉筛法)
- 回看ACM之路(暑假集训总结)
- 2017级寒假ACM集训结训赛--官方题解
- 2013ACM暑假集训总结-致将走上大三征途的我
- C++ 质数因子 | Java 分解质因数
- rqnoj-116-质数取石子-dp
- bzoj jzoj 3945. 【湖南省队集训2014】Jabberwocky 树状数组
- EXCEL自定义函数求1000以内的质数