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.
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.
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.
2 2 3
2 3 2
2 2 2
1 2
3 2 1 1
3 1 1 2
2 83 14
214 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("%d ",num); for(int i=1;i<=n;i++) { if(flag[i]) { if(i==n) printf("%d ",b[i]); else printf("%d ",b[i]); } } } return 0; }