CodeFores 665D Simple Subset(贪心)

时间:2022-05-11
本文章向大家介绍CodeFores 665D Simple Subset(贪心),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

D. Simple Subset

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

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 awith 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
首先对于每个数,找出来和它的和不是素数的数,并统计个数。然后贪心的把个数最大的那个数删除,同时,和它相关的那些数的个数就少了1,然后再选取个数最大的,直到所有数的个数为0.用了优先队列来实现。一开始的时候要把重复的数字合并起来,要不然这个方法会超时。#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#include <vector>
#include <queue>

using namespace std;
#define MAX 1000
typedef long long int LL;
vector<int> a[MAX+5];
int b[MAX+5];
int c[MAX+5];
int tag[MAX+5];
bool flag[MAX+5];
bool t[MAX*1000+5];
int n;
struct Node
{
    int pos;
    int value;
    Node(){};
    Node(int pos,int value){this->pos=pos;this->value=value;}
    friend bool operator<(Node a,Node b){return a.value<b.value;}
};
priority_queue<Node>q;
bool isPrime(LL x)
{
    if(x==1) return 0;
    if(x==2) return 1;
    for(int i=2;i*i<=x;i++)
    {
        if(x%i==0)
            return 0;
    }
    return 1;
}
int main()
{
   while(scanf("%d",&n)!=EOF)
   {

   for(int i=1;i<=n;i++)
	   scanf("%d",&c[i]);
   memset(t,false,sizeof(t));
   int cnt=0;
   for(int i=1;i<=n;i++)
   {
       if(!t[c[i]]||c[i]==1)
	   {
          b[++cnt]=c[i];
		  t[c[i]]=true;
	   }
   }
   n=cnt;
    memset(tag,0,sizeof(tag));
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(i==j) continue;
            if(!isPrime(b[i]+b[j]))
            {a[i].push_back(j);tag[i]++;}
        }
    }
    for(int i=1;i<=n;i++)
        q.push(Node(i,tag[i]));
    memset(flag,true,sizeof(flag));
    int num=n;
    while(!q.empty())
    {
        Node term=q.top();
        q.pop();
        if(term.value!=tag[term.pos]) continue;
        if(term.value==0)
            break;
        flag[term.pos]=false;num--;
        for(int i=0;i<a[term.pos].size();i++)
        {
            if(flag[a[term.pos][i]]==false) continue;
            tag[a[term.pos][i]]--;
            q.push(Node(a[term.pos][i], tag[a[term.pos][i]]));
        }
    }
    printf("%dn",num);
    for(int i=1;i<=n;i++)
    {
        if(flag[i])
        {
            if(i==n)
            printf("%dn",b[i]);
            else
                printf("%d ",b[i]);
        }
    }
   }
    return 0;
}