Description
由于去NOI的火车“堵”了数不清时间,小Z和小D打完ETG,闲着无聊开始看今年的JSOI省选题,并尝试着修改题目:
对于一个长度为L ≥ 2的序列,X:x1,x2,...,xL ,如果满足对于任意的1 ≤ i < j ≤ L,均有 xi+xj为质数,则他们把X称为一个“质数序列”。
现在有一个长度为N的序列,A:a1,a2,...,aN ,他希望从中选取一个包含元素最多的子序列,使得这个子序列是一个质数序列。如果元素个数相同,则使子序列之和最大(在此意义下,保证有唯一解)。
因为他们还要xx,所以这个任务就交给你了。
对于一个长度为L ≥ 2的序列,X:x1,x2,...,xL ,如果满足对于任意的1 ≤ i < j ≤ L,均有 xi+xj为质数,则他们把X称为一个“质数序列”。
现在有一个长度为N的序列,A:a1,a2,...,aN ,他希望从中选取一个包含元素最多的子序列,使得这个子序列是一个质数序列。如果元素个数相同,则使子序列之和最大(在此意义下,保证有唯一解)。
因为他们还要xx,所以这个任务就交给你了。
Input
输入第一行包含一个正整数 N。
接下来一行包含N个正整数,依次描述 a1,a2,...,aN。
接下来一行包含N个正整数,依次描述 a1,a2,...,aN。
Output
输出两行,第一行一个整数L,表示最长质数子序列的长度,第二行L个整数从小到大输出,表示最长质数子序列(元素个数相同,则使子序列之和最大)。
Sample Input
3
2 3 4
Sample Output
2
3 4
Data Constraint
对于30%的数据满足N<=100 。
对于60%的数据满足N<=1000 ,ai<=5,000,000 。
对于100%的数据满足N<=1000 ,1<=ai<=15,000,000 。
对于60%的数据满足N<=1000 ,ai<=5,000,000 。
对于100%的数据满足N<=1000 ,1<=ai<=15,000,000 。
做法:思考一下就会发现,本体其实只有3种情况
{
若序列中不存在1或只有1个1,那么最长的长度一定为2,此时只要找两个最大的就好
若序列中存在2个1,那么寻找序列中最大的一个能和1组成质数的数,若找不到,视作情况1
若序列中存在3个及以上的1,那么参考情况2,若找不到,输出1的个数和所有的1即可
}
1 #include <cstdio> 2 #include <iostream> 3 #include <cmath> 4 #include <cstring> 5 #define N 1007 6 #define M 30000007 7 #define LL long long 8 using namespace std; 9 int n,zs[M/2],T1; 10 LL a[N],sum,q,p; 11 bool b[M + 20]; 12 13 void Pre_work(){ 14 for(int i=2;i<=M;i++){ 15 if(!b[i]) zs[++zs[0]]=i; 16 for(int j=1;j<=zs[0];j++) 17 if((LL)i*zs[j]<=M-5) b[i*zs[j]]=1; 18 else break; 19 } 20 } 21 22 int main(){ 23 Pre_work(); 24 memset(a,0,sizeof(a)); 25 q=0,p=0,sum=0; 26 scanf("%d",&n); 27 for(int i=1;i<=n;i++){ 28 scanf("%lld",&a[i]); 29 if (a[i]==1) T1++; 30 } 31 if (T1>2){ 32 for (int i=1;i<=n;i++) 33 if (!b[a[i]+1]) q=max(q,a[i]); 34 if (q!=0 && q!=1){ 35 printf("%d\n",T1+1); 36 for (int i=1;i<=T1;i++) printf("1 "); 37 printf("%lld",q); 38 } 39 else{ 40 printf("%d\n",T1); 41 for (int i=1;i<=T1;i++) printf("1 "); 42 } 43 return 0; 44 } 45 else if (T1==2){ 46 for (int i=1;i<=n;i++) 47 if (!b[a[i]+1]) q=max(q,a[i]); 48 if (q!=0 && q!=1){ 49 printf("%d\n",T1+1); 50 for (int i=1;i<=T1;i++) printf("1 "); 51 printf("%lld",q); 52 return 0; 53 } 54 } 55 else{ 56 for(int i=1;i<n;i++) 57 for(int j=i+1;j<=n;j++) 58 if (!b[a[i]+a[j]]){ 59 if(a[i]+a[j]>sum){ 60 q=a[i],p=a[j]; 61 sum=q+p; 62 } 63 } 64 printf("2\n"); 65 if (q>p) swap(q,p); 66 printf("%lld %lld", q, p); 67 } 68 }