反物质
【问题描述】
  物理学家有一种假设,世界上存在反物质,反物质遇到正常的物质会发生湮灭。

  假设现在有 n 个粒子,每个粒子的种类用一个 m 以内的正整数表示。现在
要将这些粒子按一定顺序放入一个封闭空间。封闭空间最初什么都没有。

  每当放进一个粒子时,若封闭空间为空或封闭空间中的粒子和放入的粒子
种类相同,这个粒子将留在封闭空间中;若封闭空间中的粒子和放入的粒子种
类不同,则封闭空间中会有一个粒子和放入的粒子抵消(即湮灭)。

  判断是否存在一种排序方案,使得最后封闭空间中有种类编号为“1”的粒
子存在。若存在,最大化最后种类编号为“1”的粒子个数。若多种方案,要求
字典序最小。

【输入格式】
  第 1 行:n 和 m,用空格隔开。
  第 2 到 m+1 行:第 i+1 行代表第 i 种粒子有多少个。每种粒子至少有 1 个。
保证粒子总数是 n。
【输出格式】
  第 1 行:如果最后封闭空间中可以有编号为“1”的粒子存在,输出 YES,否则输出 NO。
  如果第一行输出了 YES,还需继续输出:
  第 2 行:这一行输出最后“1”的个数。
  第 3…n+2 行:输出在能最后“1”有最大数的排序方案里,字典序最小的方案。
  如果第一行输出了 NO,就不必输出其他内容了
【样例输入】
  5 3
  2
  1
  2
【样例输出】
  YES
  1
  1
  3
  2
  3
  1
【数据规模和约定】
  对于 30%的数据, n<=10
  对于 60%的数据, n<=1000
  对于 100%的数据, 1<=m<=n<=10^6

考场解题:
  哎呦呦呦,这题只输出最多剩下多少还好,这按字典序排列可就
难为死人啦,这咋排,管他呢,先判断下‘NO’的情况吧,说不定还
能的点分,如果某种粒子的个数超过了总个数的一半,那么一定不能
有‘1’粒子,与之共存,则输出‘NO’ ,此时还需要注意者最多的是
不是 ‘1’ 粒子, 也就到这思路靠谱点, 后边的瞎想就不在此多说了,
总之就是看啥顺眼打打试试吧。

预计得分:10-20(还不得有个‘NO’送点分)
实际得分:0(没爱了)

正解:
代码理解吧:

  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. const int N = ;
  5. int n,m;
  6. int num[N];
  7. int big=;
  8. int cc[N],xu[N];
  9. int last[N];
  10. bool cmp(int x, int y)
  11. {
  12. return(num[x]<num[y]);
  13. }
  14. void print()
  15. {
  16. int i,sum=;
  17. for(i=; i<=m; i++)
  18. xu[i]=i;
  19. sort(xu+,xu+m+,cmp);
  20. /* for(i=1;i<=m;i++)
  21. cc[num[i]]++;
  22. //cc[x]表示粒子数量为x的有几种
  23. for(i=1;i<=n;i++)
  24. cc[i]+=cc[i-1];
  25. //cc[x]表示粒子数量不超过x的有几种
  26. for(i=1;i<=m;i++)
  27. xu[cc[num[i]]--]=i;
  28. //把各种粒子按照num[i]从小到大排序
  29. */
  30. for(i=; i<=m; i++)
  31. {
  32. last[i]=num[i];//last剩下多少个i这种粒子
  33. sum+=last[i];//还有多少该抵消的粒子没抵消
  34. }
  35. int top=m; //xu中下标超过top的,num都大于sum/2
  36. int tot=; //现在封闭空间中有多少个粒子,粒子编号小于s
  37. int s=; //现在还剩下的粒子中编号最小的
  38. while()
  39. {
  40. while(s<=m && !last[s])
  41. s++;
  42. if(s>m)
  43. break;
  44. if(!tot)
  45. {
  46. tot=last[s];
  47. last[s]=;
  48. for(i=; i<=tot; i++)
  49. printf("%d\n",s);
  50. }
  51. else
  52. {
  53. sum-=;
  54. tot--;
  55. while(top && num[xu[top]]>sum/)
  56. top--;
  57. for(i=m; i>top; i--)
  58. {
  59. if(last[xu[i]]>sum/)
  60. break;
  61. }
  62. if(i>top)
  63. {
  64. printf("%d\n",xu[i]);
  65. last[xu[i]]--;
  66. }
  67. else
  68. {
  69. printf("%d\n",s);
  70. last[s]--;
  71. }
  72. }
  73. }
  74. }
  75. int main()
  76. {
  77. freopen("anti.in","r",stdin);
  78. freopen("anti.out","w",stdout);
  79. int i;
  80. scanf("%d%d%d",&n,&m,&num[]);
  81. for(i=; i<=m; i++)
  82. {
  83. scanf("%d",&num[i]);
  84. if(num[i]*>n-num[])
  85. big=i; // 找出最大种类的数目
  86. }
  87. if(big)
  88. {
  89. int remain=num[big]-(n-num[]-num[big]);
  90. if(num[]>remain)
  91. {
  92. if(m>) //如果两类,先输出1 2 结果都一样,字典序最小先输出 1
  93. {
  94. int t=num[]-remain;
  95. num[]=remain;
  96. printf("YES\n%d\n",t);
  97. print();
  98. for(i=; i<=t; i++)
  99. printf("1\n");
  100. }
  101. else
  102. {
  103. int t=num[]-remain; //t表示要先输出多少个 1
  104. printf("YES\n%d\n",t);
  105. for(i=; i<=num[]; i++)
  106. printf("1\n");
  107. for(i=; i<=num[]; i++)
  108. printf("2\n"); //最后输出几个 1
  109. }
  110. }
  111. else
  112. printf("NO\n"); //若big占比重大, 可以抵消全部的1,则输出‘NO’;
  113. }
  114. else
  115. {
  116. int t;
  117. if((n-num[])%==)
  118. {
  119. if(num[]<=)
  120. {
  121. printf("NO\n");
  122. return ;
  123. }
  124. t=num[]-;
  125. num[]=;
  126. }
  127. else
  128. {
  129. if(num[]<)
  130. {
  131. printf("NO\n");
  132. return ;
  133. }
  134. t=num[];
  135. num[]=;
  136. }
  137. printf("YES\n%d\n",t);
  138. print();
  139. for(i=; i<=t; i++)
  140. printf("1\n");
  141. }
  142. return ;
  143. }

细节多,心累!

5.1 qbxt 一测 T3的更多相关文章

  1. 7.20试机测 T3 阶乘之和 暴力AC题解

    7.20试机测  T3 阶乘之和 暴力AC题解 题外话:此乃本蒟蒻发表的第一篇题解,大家多多关照,支持一下,谢谢 题面 3.阶乘之和(sum.pas/in/out) 问题描述: 给定一个非负整数 n, ...

  2. NOI十连测 第六测 T3

    思路:考试的时候我非常地**,写了圆并,然后还TM写了半平面交和三角剖分,虽然只有30分..但是看在我写了500行的份上还是挂着吧.. #include<cstdio> #include& ...

  3. NOI十连测 第四测 T3

    思路: 算法一:可以n^2找出每个点的权值,然后n^2做完,预计得分10 算法二:随机找点然后每次找最高..貌似只有10分?然而考试的时候煞笔了,边界设成inf.. 算法三:随机找几个点,然后随机爬山 ...

  4. 5.1 qbxt 一测 T2

    求和[问题描述] 组合数 C(n,m)是从 n 个物品中取 m 个的方案数. C(n,m)=(n!)/(m!(n-m)!) 斐波那契数列 F 满足,F[0]=F[1]=1,n≥2 时 F[n]=F[n ...

  5. 5.1 qbxt 一测 T1

    禁咒检验 (3MB / 2s)[问题描述] 在古老的世界里,有一个神奇的职业叫做魔法师. 魔法师的特点是会魔法,施放魔法需要念咒语. 在古老的世界里,有一个神奇的职业叫做码农.码农的工作是帮助魔法师记 ...

  6. 暑假集训D11总结

    %dalao 今天某学长来讲一个极其高深的数据结构——线段树(woc哪里高深了),然而并没有时间整理笔记= =,所以明天在扔笔记咯= = 考试 今天考试,一看数据范围,woc暴力分给的真足,然后高高兴 ...

  7. noip2018——题解&总结

    近期正在疯狂复习某些东西,这篇博客尽量年底更完……(Day2T2除外) 好了,所有的希望都破灭了,原来这就是出题人的素质.——一个被欺骗的可怜 $OIer$ 人生中倒数第三次 $noip$ (Mayb ...

  8. CSP-S2021 退役记

    首先大家一起恭喜博主以5pts之差与省三擦肩而过!(nmd爷去年都省三今年成功打铁了) 果然这个菜鸡一年不如一年了 upd:T3死在多测上了,随便一个40+28的人可以吊打我 Day -2: 模拟赛, ...

  9. 弱省互测#2 t3

    题意 给出\(n\)个01字节和\(m\)个01字节,要求用后者去匹配前者,两个串能匹配当且仅当除了每个字节末位不同,其他位都要相同.问匹配后者至少有多少个末位不同.(\(1 \le m \le n ...

随机推荐

  1. Go语言中的代码重用 - 继承还是组合?

    故事要从我在一个项目中,想要假装的专业一点而遇到的一个陷阱说起. 代码重用 在这个项目中,我们已经有了类似如下的代码: package main import ( "fmt" ) ...

  2. 【WIP】swift3的timer的用法

    创建: 2017/10/14   更新: 2017/10/14 标题加上[WIP],补充创建时间     回家再写

  3. 关于long long int和__int64用%I64d和%lld输出在不同编译语言下的正确性

    http://blog.csdn.net/febr2/article/details/52068357 这个网址最下面

  4. Educational Codeforces Round 19 C

    Description Petya recieved a gift of a string s with length up to 105 characters for his birthday. H ...

  5. Two Flowers CodeChef - TWOFL

    https://vjudge.net/problem/CodeChef-TWOFL 先把颜色相同的合并成一个点,建好图,枚举要取的两种颜色(根据图中所有边决定哪些组合要枚举)即可 错误记录: 1.写了 ...

  6. 线段树(单点更新)/树状数组 HDOJ 1166 敌兵布阵

    题目传送门 /* 线段树基本功能:区间值的和,修改某个值 */ #include <cstdio> #include <cstring> #define lson l, m, ...

  7. Linux文件和目录的777、755、644权限解释

    Linux文件和目录的权限 1.文件权限 在linux系统中,文件或目录的权限可以分为3种: r:4 读 w:2 写 x:1  执行(运行)-:对应数值0 数字 4 .2 和 1表示读.写.执行权限 ...

  8. Android Studio编译开源项目(含NDK开发)常见报错

    1.未设置NDK的路径 Error:Execution failed for task ':library:ndkBuild'. > A problem occurred starting pr ...

  9. [已读]响应式web设计实践

    薄的一本,彩印,书质量和内容都不错. 响应设计三要素:媒体查询.流动布局.自适应图片.

  10. 堆参数-XMS 与-XMX的说明

    XMS : JVM初始分配的堆内存 XMX : JVM最大允许分配的堆内存,按需分配 堆内存分配: JVM初始分配的堆内存由-Xms指定,默认是物理内存的1/64: JVM最大分配的堆内存由-Xmx指 ...