PAT甲题题解-1029. Median (25)-求两序列的中位数,题目更新了之后不水了
这个是原先AC的代码,但是目前最后一个样例会超内存,也就是开不了两个数组来保存两个序列了,意味着我们只能开一个数组来存,这就需要利用到两个数组都有序的性质了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <queue>
using namespace std;
/*
水死了
*/
const int maxn=+;
int seq[maxn]; int main()
{
int n1,n2;
scanf("%d",&n1);
for(int i=;i<n1;i++){
scanf("%d",&seq[i]);
}
scanf("%d",&n2);
for(int i=;i<n2;i++){
scanf("%d",&seq[n1+i]);
}
sort(seq,seq+n1+n2);
int n=n1+n2;
int mid;
if(n%==){
mid=n/;
}
else{
mid=n/+;
}
printf("%d\n",seq[mid-]);
return ;
}
由于直接开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,所以不会影响。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
/*
水死了
4 11 12 13 14
5 1 2 3 4 5 4 11 12 13 14
5 9 10 15 16 17 4 4 5 6 10
5 5 7 8 12 13
7比10小,但是比6大,那还要用7替换掉10 由于直接开4*10^5的数组,最后一个样例会超出内存,所以显然应该只能保存一个数组,不能两个都保存。
那么这就要利用到两个数组都是有序的性质了。 4 4 5 6 10
5 5 7 8 12 13
*/
const int maxn=+;
int seq[maxn]; int main()
{
int n1,n2;
int a;
scanf("%d",&n1);
for(int i=;i<n1;i++){
scanf("%d",&seq[i]);
}
scanf("%d",&n2);
int mid=(n1+n2+)/-; //即中位数对应的索引为mid-1
int target;
if(mid>=n1)
target=n1-;
else
target=mid;
//printf("mid:%d,target:%d\n",mid,target);
int ans=-;
for(int i=;i<n2;i++){
scanf("%d",&a);
//printf("a:%d\n",a);
if(a<seq[target]){
if(mid>){
if(mid==target && a>=seq[mid-])
seq[mid]=a;
else{
mid--;
if(mid<target)
target--;
}
//printf("mid:%d,target:%d\n",mid,target);
}
else{
/*
mid==0,第二行序列已经读取了mid个
此时a<seq[mid]的话,那么总共有mid+1个数<seq[0],那么中位数就是a了
*/
ans=a;
break;
}
}
else{
if(mid>=n1){
int left=mid-n1;
seq[n1]=a;
for(int j=n1+;j<=mid;j++){
scanf("%d",&seq[j]);
}
ans=seq[mid];
break;
}
else
ans=seq[mid];
}
}
if(ans==-)
ans=seq[mid];
printf("%d\n",ans);
return ;
}
PAT甲题题解-1029. Median (25)-求两序列的中位数,题目更新了之后不水了的更多相关文章
- PAT甲题题解-1003. Emergency (25)-最短路径+路径数目
给出n个城市,m条边,起始点c1和目的点c2接下来给出n个城市的队伍数以及m条双向边问你求c1到c2的所有最短路径数目,以及其中经过的最多队伍数 先最短路dijkstra,同时建立vector数组pr ...
- PAT甲题题解-1010. Radix (25)-二分搜索
题意:给出n1和n2,以及其中一个数的进制,问另一个数是多少进制的情况下,才会是两个数相等.不存在的话,则输出Impossible 这题思路很简单,但是要考虑的比较多,在简单题里面算是比较好的. 有两 ...
- PAT甲题题解-1032. Sharing (25)-链表水题
#include <iostream> #include <cstdio> #include <algorithm> #include <string.h&g ...
- PAT甲题题解-1070. Mooncake (25)-排序,大水题
#include <iostream> #include <cstdio> #include <algorithm> #include <string.h&g ...
- PAT甲题题解-1078. Hashing (25)-hash散列
二次方探测解决冲突一开始理解错了,难怪一直WA.先寻找key%TSize的index处,如果冲突,那么依此寻找(key+j*j)%TSize的位置,j=1~TSize-1如果都没有空位,则输出'-' ...
- PAT甲题题解-1125. Chain the Ropes (25)-贪心水题
贪心水题,每次取最短的两个绳子合并,长度缩减成一半 #include <iostream> #include <cstdio> #include <algorithm&g ...
- PAT甲题题解-1007. Maximum Subsequence Sum (25)-求最大子区间和
题意:给出n个数,求最大连续的子区间和,并且输出该区间的第一个和最后一个数. 如果所有数都小于0,那么则输出0,第一个数和最后一个数. 看数据k的范围,就知道肯定不能两层for循环来求区间和,O(n^ ...
- PAT甲题题解-1013. Battle Over Cities (25)-求联通分支个数
题目就是求联通分支个数删除一个点,剩下联通分支个数为cnt,那么需要建立cnt-1边才能把这cnt个联通分支个数求出来怎么求联通分支个数呢可以用并查集,但并查集的话复杂度是O(m*logn*k)我这里 ...
- PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...
随机推荐
- mysql host'XXX' is not allowed to connect to this mysql server
错误的原因一般是没有添加 IP可远程的权限. 首先以 root 帐户登陆 MySQL 1.在 Windows 主机中点击开始菜单,运行,输入“cmd”,进入控制台,然后cd 进入MySQL 的 bin ...
- MPT树详解
目录 MPT树定义 MPT树的作用是什么? 前缀树与默克尔树 前缀树 默克尔树 三种节点类型 MPT中的Merkle HP编码 官方表示形式 相关MPT树 参考目录 @ MPT树定义 一种经过改良的. ...
- 【python27】猜随机数的小游戏
游戏规则: 猜一个随机数,如果猜对了就给出相应的猜成功提示语(自定义文字),如果猜大或者是猜小了,给出对应的提示,但总的猜次数为三次,每猜错一次重新猜时,给用户提示所剩余的猜次数 实现如下: # -* ...
- aused by: org.apache.xmlbeans.SchemaTypeLoaderException: XML-BEANS compiled schema: Incompatible min
版权声明:转载请注明出处 https://blog.csdn.net/seashouwang/article/details/24025871 6.导入Word2007-docx,Excel-2007 ...
- [AHOI2014/JSOI2014]支线剧情
题目 有源汇上下界最小费用可行流 首先注意到要求是每一条边都经过至少一次,所以对于每一条边我们设成\([1,\infty]\)就好了 另外所有点都能结束剧情,所有点都要向汇点\(t\)连一条\([0, ...
- win10家庭版安装DockerToolbox-18.03.0-ce
下载DockerToolbox-18.03.0-ce.exe https://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/ 点击安 ...
- JavaScript函数注意点
1.return 请注意,函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回.因此,函数内部通过条件判断和循环可以实现非常复杂的逻辑. 如果没有return语句,函数执行 ...
- Android“寄生兽”漏洞技术分析
一.关于app的缓存代码 安卓的应用程序apk文件是zip压缩格式的文件,apk文件中包含的classes.dex文件相当于app的可执行文件,当app运行后系统会对classes.dex进行优化,生 ...
- jQuery.bsgrid
http://thebestofyouth.com/bsgrid/ 支持json.xml数据格式,皮肤丰富并且容易定制,支持表格编辑.本地数据.导出参数构建等实用便捷的功能,容易扩展,更拥有丰富的示例 ...
- 20155310 Exp9 Web安全基础实践
20155310 Exp9 Web安全基础实践 基础问题 SQL注入攻击原理,如何防御? SQL注入漏洞是指在Web应用对后台数据库查询语句处理存在的安全漏洞.也就是,在输入字符串中嵌入SQL指令,在 ...