这个是原先AC的代码,但是目前最后一个样例会超内存,也就是开不了两个数组来保存两个序列了,意味着我们只能开一个数组来存,这就需要利用到两个数组都有序的性质了。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <string.h>
  5. #include <cmath>
  6. #include <queue>
  7. using namespace std;
  8. /*
  9. 水死了
  10. */
  11. const int maxn=+;
  12. int seq[maxn];
  13.  
  14. int main()
  15. {
  16. int n1,n2;
  17. scanf("%d",&n1);
  18. for(int i=;i<n1;i++){
  19. scanf("%d",&seq[i]);
  20. }
  21. scanf("%d",&n2);
  22. for(int i=;i<n2;i++){
  23. scanf("%d",&seq[n1+i]);
  24. }
  25. sort(seq,seq+n1+n2);
  26. int n=n1+n2;
  27. int mid;
  28. if(n%==){
  29. mid=n/;
  30. }
  31. else{
  32. mid=n/+;
  33. }
  34. printf("%d\n",seq[mid-]);
  35. return ;
  36. }

由于直接开4*10^5的数组,最后一个样例会超出内存,所以显然应该只能保存一个数组,不能两个都保存。
那么这就要利用到两个数组都是有序的性质了。

拿例子来说吧
Case1:
  4 11 12 13 14 mid
  5 9 10 15 16 17
方便起见,第一个数组为seq1,第二个数组seq2,整个数组seq12,我们可以将seq1理解为seq12的前一半数组。
我们先存第一个数组,存入到seq1里面
mid为中位数索引,这里mid=(4+5+1)/2-1=4,即seq1[4]。
但由于此时seq1[4]上是没有数字的,我们又设定了一个target=n1-1,即读取seq2的时候,会和seq1[target]比较值
1.mid=4,target=3
2.读取9,9<seq1[target],那么意味着9我可以插入到seq12的前一半数组中去,前一半数组多了一个元素,mid肯定要-1。
mid=mid-1=3,target=3
3.读取10,10<seq1[target],同样的,10也可以插入到前一半中去
mid=mid-1=2,由于此时mid<target了,所以也要更新下target=target-1=2,现在target和mid就指向同一个了
4.读取15,15是大于seq1[target]的,那也就是意味着,后面所有的数都是大于seq1[target]的,那么中位数显然就是seq1[target]=seq1[mid]

但是,细心的同学会发现,不对呀,万一此时mid和target不相同呢,看下面例子
Case2:
  3 11 12 13 _ mid
  6 9 14 15 16 17 18
1.mid=4,target=2
2.9<13,mid=3,target=2
3.14>13,也就是说我们需要将从14开始的数字,填充到[n1,mid]区间,就变成了 11 12 13 (14) (15)
4.中位数即为seq1[4]=15

Case3:
既然mid有可能会>=n1的情况,那也有可能mid<0呀
  4 11 12 13 14 mid
  5 1 2 3 4 5
1.mid=4,target=3
2.1<14,mid=target=3
3.2<14,mid=target=2
4.3<13,mid=target=1
5.4<12,mid=target=0
6.5<11,发现mid不可能再减小了,由于5是第mid(4)+1个,所以5刚好就是中位数。

但此时仍然有一个样例没过,发现如下情况没考虑:
Case4:
  4 4 5 6 10
  5 5 7 8 12 13
1.mid=4,target=3
2.5<10,mid=target=3
3.7<10,如果仅仅更新mid和target,mid和target=2,那么接下来8>6,最后的结果为6,但实际上为7
原因是7比6大,所以7不可能插到6的前面,所以只能7替换掉10。
替换是在mid和target相等的情况下,如果此时mid=4,target=3,那么此时的中位数相当于seq[target+1]。
7比10小,当把7插入到10的前面,mid--,中位数是变为了10,所以不会影响。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <string.h>
  5. #include <cmath>
  6. #include <queue>
  7. #define INF 0x3f3f3f3f
  8. using namespace std;
  9. /*
  10. 水死了
  11. 4 11 12 13 14
  12. 5 1 2 3 4 5
  13.  
  14. 4 11 12 13 14
  15. 5 9 10 15 16 17
  16.  
  17. 4 4 5 6 10
  18. 5 5 7 8 12 13
  19. 7比10小,但是比6大,那还要用7替换掉10
  20.  
  21. 由于直接开4*10^5的数组,最后一个样例会超出内存,所以显然应该只能保存一个数组,不能两个都保存。
  22. 那么这就要利用到两个数组都是有序的性质了。
  23.  
  24. 4 4 5 6 10
  25. 5 5 7 8 12 13
  26. */
  27. const int maxn=+;
  28. int seq[maxn];
  29.  
  30. int main()
  31. {
  32. int n1,n2;
  33. int a;
  34. scanf("%d",&n1);
  35. for(int i=;i<n1;i++){
  36. scanf("%d",&seq[i]);
  37. }
  38. scanf("%d",&n2);
  39. int mid=(n1+n2+)/-; //即中位数对应的索引为mid-1
  40. int target;
  41. if(mid>=n1)
  42. target=n1-;
  43. else
  44. target=mid;
  45. //printf("mid:%d,target:%d\n",mid,target);
  46. int ans=-;
  47. for(int i=;i<n2;i++){
  48. scanf("%d",&a);
  49. //printf("a:%d\n",a);
  50. if(a<seq[target]){
  51. if(mid>){
  52. if(mid==target && a>=seq[mid-])
  53. seq[mid]=a;
  54. else{
  55. mid--;
  56. if(mid<target)
  57. target--;
  58. }
  59. //printf("mid:%d,target:%d\n",mid,target);
  60. }
  61. else{
  62. /*
  63. mid==0,第二行序列已经读取了mid个
  64. 此时a<seq[mid]的话,那么总共有mid+1个数<seq[0],那么中位数就是a了
  65. */
  66. ans=a;
  67. break;
  68. }
  69. }
  70. else{
  71. if(mid>=n1){
  72. int left=mid-n1;
  73. seq[n1]=a;
  74. for(int j=n1+;j<=mid;j++){
  75. scanf("%d",&seq[j]);
  76. }
  77. ans=seq[mid];
  78. break;
  79. }
  80. else
  81. ans=seq[mid];
  82. }
  83. }
  84. if(ans==-)
  85. ans=seq[mid];
  86. printf("%d\n",ans);
  87. return ;
  88. }

PAT甲题题解-1029. Median (25)-求两序列的中位数,题目更新了之后不水了的更多相关文章

  1. PAT甲题题解-1003. Emergency (25)-最短路径+路径数目

    给出n个城市,m条边,起始点c1和目的点c2接下来给出n个城市的队伍数以及m条双向边问你求c1到c2的所有最短路径数目,以及其中经过的最多队伍数 先最短路dijkstra,同时建立vector数组pr ...

  2. PAT甲题题解-1010. Radix (25)-二分搜索

    题意:给出n1和n2,以及其中一个数的进制,问另一个数是多少进制的情况下,才会是两个数相等.不存在的话,则输出Impossible 这题思路很简单,但是要考虑的比较多,在简单题里面算是比较好的. 有两 ...

  3. PAT甲题题解-1032. Sharing (25)-链表水题

    #include <iostream> #include <cstdio> #include <algorithm> #include <string.h&g ...

  4. PAT甲题题解-1070. Mooncake (25)-排序,大水题

    #include <iostream> #include <cstdio> #include <algorithm> #include <string.h&g ...

  5. PAT甲题题解-1078. Hashing (25)-hash散列

    二次方探测解决冲突一开始理解错了,难怪一直WA.先寻找key%TSize的index处,如果冲突,那么依此寻找(key+j*j)%TSize的位置,j=1~TSize-1如果都没有空位,则输出'-' ...

  6. PAT甲题题解-1125. Chain the Ropes (25)-贪心水题

    贪心水题,每次取最短的两个绳子合并,长度缩减成一半 #include <iostream> #include <cstdio> #include <algorithm&g ...

  7. PAT甲题题解-1007. Maximum Subsequence Sum (25)-求最大子区间和

    题意:给出n个数,求最大连续的子区间和,并且输出该区间的第一个和最后一个数. 如果所有数都小于0,那么则输出0,第一个数和最后一个数. 看数据k的范围,就知道肯定不能两层for循环来求区间和,O(n^ ...

  8. PAT甲题题解-1013. Battle Over Cities (25)-求联通分支个数

    题目就是求联通分支个数删除一个点,剩下联通分支个数为cnt,那么需要建立cnt-1边才能把这cnt个联通分支个数求出来怎么求联通分支个数呢可以用并查集,但并查集的话复杂度是O(m*logn*k)我这里 ...

  9. PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...

随机推荐

  1. mac系统默认python3.6

    1. 终端打开.bash_profile文件 终端输入:open ~/.bash_profile   2. 打开.bash_profile文件后在内容最后添加  alias python=" ...

  2. Alpha冲刺报告(5/12)(麻瓜制造者)

    今日已完成 明日计划 部分api示意图 燃尽图 scrum会议照片 今日已完成 邓弘立: 完成部分首页逻辑功能 符天愉: 写代码写着写着想起来昨天的登录接口有个非常zz的逻辑错误,今天修改完后应该没有 ...

  3. 【Python】新建自定义个数的自定义长度名字

    # -*- coding:utf-8 -*- import random def CreateRandomName(number,length): """ :param ...

  4. 【洛谷】【动态规划+单调队列】P1714 切蛋糕

    [题目描述:] 今天是小Z的生日,同学们为他带来了一块蛋糕.这块蛋糕是一个长方体,被用不同色彩分成了N个相同的小块,每小块都有对应的幸运值. 小Z作为寿星,自然希望吃到的第一块蛋糕的幸运值总和最大,但 ...

  5. laravel扩展推荐

    1. Intervention/image 图片处理 2.Laravel User Agent 轻松识别客户端信息 3.OAuth 2.0 支持 4.页面面包屑工具 5.计划任务分发器(直接可替换掉 ...

  6. python requests 简单实现易班登录,自动点赞,评论,发表

    小编能力有限,本文纯属瞎编,如有雷同,你去打辅导员涩 一.前戏 有个操蛋,操蛋,操蛋的辅导员促使小编成长,原因:易班需要活跃度,辅导员安排班上每个人必须去易班上 写文章,写评论,发投票...  我觉得 ...

  7. JavaScript标准对象

    1.Date var now = new Date(); now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST) now.getFullYear(); // 2 ...

  8. 2019年春季学期《C语言程序设计II》助教注意事项

    本学期<C语言程序设计II>课程安排 理论课时24(1-12周),实验课时8(13周),课程设计课时16(14-15周) 理论课教学内容 附:教学进度表 本学期实验课和课程设计参考教材 & ...

  9. vxlan 简单理解 vs calico 网络模型

    1.vxlan(virtual Extensible LAN)虚拟可扩展局域网,是一种overlay的网络技术,使用MAC in UDP的方法进 行封装,共50字节的封装报文头. 2.VTEP为虚拟机 ...

  10. Scala--映射和元组

    一.构造映射 val scores = Map("Jim"->10, ("Tom",20), "Sam"->44) //key- ...