用long int写一直爆内存,网上一查答案只会是int,心态崩了。。。
题目大意是给你两个序列,求他们合并之后的中位数。
首先,如果用数组写,内存就炸了。sort一时爽,一直sort一直爽
中位数,根据算法导论的定义,当n为奇数时,他是第(n+1)/2个顺序统计量;当n为偶数时,他是第n/2个顺序统计量。通俗来说,就是这个数前面有p个,后面有p个。那么我们只需要找到前p个数就知道中位数了。题目给了两个数列,很明显要用队列来做。
这题输入的序列已经是升序了所以可以直接用队列存(想想为什么)。先把第一列数用一个队列q1存起来,然后处理第二列q2。比较q1.top()和q2.top(),谁小就让它出队。如果已经出了(m+n-1)/2个数了,答案最终就是这两个队列中最小的top()。如果没有,剩下未空的队列继续出队得到答案。
这里有两个点需要注意一下,在处理第二个序列时,边进队列边处理可以减少内存开销。还有就是为每个队列都在最后push一个INT_MAX,这样处理起来比较方便。
#include<bits/stdc++.h> #define maxn 200005 #define INF 0x3f3f3f3f using namespace std; typedef long long ll; int n,m,p,cnt,ans,x; queue<int> q1,q2; int main() { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&x); q1.push(min(x,INT_MAX)); } q1.push(INT_MAX); scanf("%d",&m); cnt=0; for(int i=0;i<m;i++) { scanf("%d",&x); q2.push(min(x,INT_MAX)); if(cnt==(n+m-1)/2) { ans=min(q1.front(),q2.front()); printf("%d\n",ans); return 0; } if(q2.front()>q1.front()) q1.pop(); else q2.pop(); cnt++; } q2.push(INT_MAX); for(;cnt<(n+m-1)/2;cnt++) { if(q2.front()>q1.front()) q1.pop(); else q2.pop(); } ans=min(q1.front(),q2.front()); printf("%d\n",ans); return 0; }