您的位置:首页 > 其它

Codeforces 665D. Simple Subset

2016-04-23 18:14 246 查看
[align=center]time limit per test[/align]
[align=center]1 second[/align]
[align=center]memory limit per test[/align]
[align=center]256 megabytes[/align]
[align=center]input[/align]
[align=center]standard input[/align]
[align=center]output[/align]
[align=center]standard output[/align]
A tuple of positive integers {x1, x2, ..., xk}
is called simple if for all pairs of positive integers (i,  j) (1  ≤ i  <  j ≤ k),
xi  +  xj is a prime.

You are given an array a with
n positive integers a1,  a2,  ...,  an
(not necessary distinct). You want to find a simple subset of the array
a with the maximum size.

A prime number (or a prime) is a natural number greater than
1 that has no positive divisors other than 1 and itself.

Let's define a subset of the array a as a tuple that can be obtained from
a by removing some (possibly all) elements of it.

Input

The first line contains integer
n (1 ≤ n ≤ 1000) — the number of integers in the array
a.
The second line contains n integers
ai (1 ≤ ai ≤ 106)
— the elements of the array a.

Output

On the first line print integer
m — the maximum possible size of simple subset of
a.
On the second line print m integers
bl — the elements of the simple subset of the array
a with the maximum size.
If there is more than one solution you can print any of them. You can print the elements of the subset in any order.

Examples

Input
2
2 3


Output
2
3 2


Input
2
2 2


Output
1
2


Input
3
2 1 1


Output
3
1 1 2


Input
2
83 14


Output
2
14 83


[align=left]
[/align]

题解

       It has been a long day from my last blog. 人生莫名其妙地改变了轨迹……总之又开始做一些题了。今后的文章大多都并不是为了提供题解而写,而是为了提醒自己一些写法、算法、数据结构之类的,可能经过数次修改,并不漂亮而且可能有并不恰当的地方。
      这道题其实脑补数学规律挺简单的,但之后的判定挺麻烦的。复习了素数筛法和二分。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int n,a[1005],ct,pri[200002],mn[2000002],zz,ji,ou;
void init()
{
scanf("%d",&n);
int i;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]==1) ct++;
else if(a[i]%2==1) ji++;
else ou++;
}
}
void prime()
{
int i,j;
for(i=2;i<=2000000;i++){
if(!mn[i]) {pri[++zz]=i; mn[i]=i;}
for(j=1;j<=zz,pri[j]*i<=2000000;j++){
mn[pri[j]*i]=pri[j];
if(i%pri[j]==0) break;
}
}
}
bool check(int x)
{
int l=1,r=zz,mid;
while(l<r){
mid=(l+r)>>1;
if(pri[mid]<x) l=mid+1;
else r=mid;
}
if(pri[r]==x) return true;
return false;
}
void judge1()
{
int i,j;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++){
if((a[i]+a[j])%2==0) continue;
if(check(a[i]+a[j])){
printf("2\n%d %d\n",a[i],a[j]); return ;
}
}
printf("1\n%d\n",a[1]);
}
void judge2()
{
int i,j;
for(i=1;i<=n;i++){
if(a[i]%2!=0) continue;
if(check(a[i]+1)){
printf("2\n%d %d\n",a[i],1); return ;
}
}
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++){
if(a[i]==1||a[j]==1||((a[i]+a[j])%2==0)) continue;
if(check(a[i]+a[j])){
printf("2\n%d %d\n",a[i],a[j]); return ;
}
}
printf("1\n%d\n",a[1]);
}
void judge3()
{
int i,j;
for(i=1;i<=n;i++){
if(a[i]%2!=0) continue;
if(check(a[i]+1)){
printf("%d\n",ct+1);
for(j=1;j<=ct;j++) printf("1 ");
printf("%d\n",a[i]); return ;
}
}
printf("%d\n",ct); for(j=1;j<=ct;j++) printf("1 ");
}
void work()
{
if(ct==0){
if(ji==0||ou==0) printf("1\n%d",a[1]);
else judge1();
}
else if(ct==1){
if(ou==0) printf("1\n1");
else judge2();
}
else{
if(ou==0){
printf("%d\n",ct);
for(int i=1;i<ct;i++) printf("1 "); puts("1");
return ;
}
else judge3();
}
}
int main()
{
init(); prime(); work();
return 0;
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二分 素数筛发