Educational Codeforces Round 12 D. Simple Subset 最大团

D. Simple Subset

题目连接:

http://www.codeforces.com/contest/665/problem/D

Description

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.

Sample Input

2
2 3

Sample Output

2
3 2

Hint

题意

给你n个数,你需要找到一个最大的子集,使得这个子集中的任何两个数加起来都是质数。

题解:

无视掉1的话,我们最多选择一个奇数和一个偶数,因为奇数+奇数=偶数,偶数加偶数=偶数
所以直接暴力枚举就好了。
另外这道题如果建边的话,跑dfs直接莽一波最大团也可以……

我是一个智障,我就跑了最大团 QAQ

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
int pri[2000005];
bool flag[maxn], a[maxn][maxn];
int ans, cnt[maxn], group[maxn], n, vis[maxn];
// 最大团: V中取K个顶点,两点间相互连接
// 最大独立集: V中取K个顶点,两点间不连接
// 最大团数量 = 补图中最大独立集数

bool dfs( int u, int pos ){
    int i, j;
    for( i = u+1; i <= n; i++){
        if( cnt[i]+pos <= ans ) return 0;
        if( a[u][i] ){
             // 与目前团中元素比较,取 Non-N(i)
            for( j = 0; j < pos; j++ ) if( !a[i][ vis[j] ] ) break;
            if( j == pos ){     // 若为空,则皆与 i 相邻,则此时将i加入到 最大团中
                vis[pos] = i;
                if( dfs( i, pos+1 ) ) return 1;
            }
        }
    }
    if( pos > ans ){
            for( i = 0; i < pos; i++ )
                group[i] = vis[i]; // 最大团 元素
            ans = pos;
            return 1;
    }
    return 0;
}
void maxclique()
{
    ans=-1;
    for(int i=n;i>0;i--)
    {
        vis[0]=i;
        dfs(i,1);
        cnt[i]=ans;
    }
}
void pre()
{
    pri[1]=1;
    pri[0]=1;
    for(int i=2;i<2000005;i++)
    {
        if(pri[i])continue;
        for(int j=i+i;j<2000005;j+=i)
            pri[j]=1;
    }
}
int aa[maxn];
int main()
{
    pre();
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&aa[i]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<i;j++)
            if(!pri[aa[i]+aa[j]])
                a[i][j]=1,a[j][i]=1;
    maxclique();
    cout<<ans<<endl;
    for(int i=0;i<ans;i++)
        cout<<aa[group[i]]<<" ";
    cout<<endl;
}

你可能感兴趣的:(Educational Codeforces Round 12 D. Simple Subset 最大团)