码迷,mamicode.com
首页 > 其他好文 > 详细

[2016-04-27][codeforces][665D - Simple Subset]

时间:2016-04-27 15:34:02      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:

  • 时间:2016-04-27 15:16:14 星期三

  • 题目编号:[2016-04-27][codeforces][665D - Simple Subset]

  • 题目大意:给定n个数字的集合A,问子集最大能有多大,使得子集中两两之和是素数,输出大小和任一这样子集

  • 分析:

    • 至多一个1:
      • 首先 从A取任意3个数
      • 如果这3个数字中至多1个 1
      • 由容斥原理可知,一定有两个数之和是偶数,并且这个偶数之和大于2(一定不是素数),所以答案子集中,大于1的数字至多只能有两个,
      • 推广到整个A,就是如果A中至多含有1个1,时,子集最多只有2个数字,那么答案就是
        1. 没有两个数字之和是素数,
        2. 存在某两个数字之和是素数,(即使有多对,只能输出一对)
    • 如果多个1,那么答案就有
      1. 全部都是1
      2. 除了1之外,还有一个数字,这个数字+1之后是素数
  1. #include<cstdio>
  2. #include<cstring>
  3. using namespace std;
  4. const int maxn = 1E3 + 10;
  5. const int maxp = 1E6*2 + 10;
  6. int isnpri[maxp],a[maxn];
  7. void getpri(){
  8. memset(isnpri,0,sizeof(isnpri));
  9. for(int i = 2 ; i < maxp + 10 ; ++i){
  10. if(isnpri[i]) continue;
  11. for(int j = i * 2 ; j < maxp; j += i){
  12. isnpri[j] = 1;
  13. }
  14. }
  15. }
  16. int main(){
  17. getpri();
  18. int n,cnt1 = 0;
  19. scanf("%d",&n);
  20. for(int i = 0 ; i < n ; ++i){
  21. scanf("%d",&a[i]);
  22. if(a[i] == 1) ++cnt1;
  23. }
  24. if(cnt1 > 1){
  25. for(int i = 0 ; i < n ; ++i){
  26. if(a[i] != 1 && !isnpri[a[i] + 1]){
  27. printf("%d\n%d",cnt1 + 1,a[i]);
  28. for(int j = 0 ; j < cnt1;++j){
  29. printf(" 1");
  30. }
  31. return 0;
  32. }
  33. }
  34. printf("%d\n",cnt1);
  35. for(int j = 0 ; j < cnt1;++j){
  36. printf("1 ");
  37. }
  38. return 0;
  39. }
  40. for(int i = 0 ; i < n ; ++i){
  41. for(int j = 0 ; j < n ; ++j){
  42. if(i != j && !isnpri[a[i] + a[j]]){
  43. printf("2\n%d %d",a[i] , a[j]);
  44. return 0;
  45. }
  46. }
  47. }
  48. printf("1\n%d",a[0]);
  49. return 0;
  50. }




[2016-04-27][codeforces][665D - Simple Subset]

标签:

原文地址:http://www.cnblogs.com/qhy285571052/p/e9f833b07850fa424f923009a4f2ee6d.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!