传送门
题目大意
给你一个长度为的序列
,找到最大的子序列,使得子序列内任意两个数的和为素数
思路
因为,所以可以输出
个数。
答案最后分为四种情况:
全是个
,另一个数+
是素数
两个数和是素数
一个数
代码
int n;
int a[maxn];
bool vis[maxn];//标记非素数,0是素数
int primer[maxn/10];//存素数
int cnt=0;//记录素数个数,
void find_primer(){
for(int i=2;i <=maxn;i++){
if(!vis[i])primer[cnt++]=i;
for(int j=0;j<cnt&&primer[j]*i<=maxn;j++){
vis[i*primer[j]]=1;//筛
if(i%primer[j]==0)break;//关键!!!找到i*primer[j]的最小质因子primer[j],退出
}
}
}
int main(){
cin>>n;
find_primer();
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
sort(a+1,a+1+n);
int cnt=0;
for(int i=1;i<=n;i++){
if(a[i]==1){
cnt++;
}
else{
break;
}
}
int flag=0,tmp=1;
for(int i=cnt+1;i<=n;i++){
if(!vis[a[i]+1]){
tmp=a[i];
flag=1;
break;
}
}
if(cnt>0){
if(flag)
cnt++;
}
int flag1=0;
int ii,jj;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(!vis[a[i]+a[j]]){
flag1=1;
ii=i,jj=j;
break;
}
}
if(flag1)
break;
}
if(cnt>2){
cout<<cnt<<endl;
for(int i=1;i<cnt;i++){
cout<<a[i]<<' ';
}
cout<<tmp<<endl;
}
else if(flag1){
cout<<"2"<<endl;
cout<<a[ii]<<" "<<a[jj]<<endl;
}
else{
puts("1");
cout<<a[1]<<endl;
}
}