1029 Median [Queue]

用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;
}
View Code

猜你喜欢

转载自www.cnblogs.com/FTA-Macro/p/10592442.html