zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    eclipse卡死在search for main types 20 files to index
    多线程并发执行任务,取结果归集。终极总结:Future、FutureTask、CompletionService、CompletableFuture
    同步中的四种锁synchronized、ReentrantLock、ReentrantReadWriteLock、StampedLock
    根据CPU核心数确定线程池并发线程数
    将DataTable转换成CSV文件
    C#中DataTable转化为List<T>解析
    DotNet项目中的一些常用验证操作
    DotNet处理服务器路径的方法
    C#运用ThoughtWorks生成二维码
    C#枚举类型的常用操作总结
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5419069.html
Copyright © 2011-2022 走看看