题解 | #Running Median#被格式卡了好久,写一篇题解吧。

Running Median

https://ac.nowcoder.com/acm/problem/50940

经典对顶堆写法就可以了。依次加入元素,左边为大根堆,右边为小根堆。每次加入一个新的元素的时候判断一下是加入右边还是左边。由于保证了左右堆的数量差距<=1,所以一共三种情况我选择了枚举。另外空格和换行的问题有被恶心到,直接上代码吧。

#include<cstring>
#include<algorithm>
#include<iostream>
#include<bitset>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
int a[4];
int main()
{
   int t; cin >> t;
   while (t--)
   {
       int m, n; scanf(" %d%d", &m, &n);
       printf("%d %d\n", m, n + 1 >> 1);
       int cnt = 1;
       priority_queue<int, vector<int>, less<int>>p;//大根堆
       priority_queue<int, vector<int>, greater<int>>q;//小根堆
       for (int i = 1; i <= n; i++)
       {
           int x; scanf(" %d", &x);
           if (n == 1 || n == 2) { printf("%d", x); break; }//n=1和n=2只需要输出第一个元素就可以了,特殊样例直接打死,懒得想了。
           if (i <= 2)
           {
               a[i] = x; continue;
           }
           if (i == 3)
           {
               printf("%d ", a[1]);//因为要先保证p和q都不能为空才能进入下面写的那些if语句,不然会报错。所以在n>=3的时候先把前俩个元素按大小加进去就行了。
               sort(a + 1, a + 1 + 2);
               p.push(a[1]); q.push(a[2]);

           }
           if (p.size() < q.size())//不想耗费脑细胞了,直接三种情况讨论了。。最简捷明了了,虽然代码又臭又长我承认。
           {
               if (x <= q.top())p.push(x);
               if (x > q.top())
               {
                   int tmp = q.top();
                   q.pop();
                   q.push(x);
                   p.push(tmp);
               }
           }
           else if (p.size() == q.size())
           {
               if (x <= q.top())p.push(x);
               if (x > q.top())
               {
                   int tmp = q.top();
                   q.pop();
                   q.push(x);
                   p.push(tmp);
               }
           }
           else if (p.size() > q.size())
           {
               if (x >= p.top())q.push(x);
               if (x < p.top())
               {
                   int tmp = p.top();
                   p.pop();
                   p.push(x);
                   q.push(tmp);
               }
           }
           if (p.size() - q.size() == 1 && i != n && i != n - 1) { cnt++; printf("%d%c", p.top(), cnt % 10 == 0 ? '\n' : ' '); }//如果不是最后一个元素该咋咋地
           else if (p.size() - q.size() == -1 && i != n && i != n - 1) { cnt++; printf("%d%c", q.top(), cnt % 10 == 0 ? '\n' : ' '); }
           else if (p.size() - q.size() == 1 && (i == n || i == n - 1)) { cnt++; printf("%d", p.top()); }
           //这里是特判了最后一个元素,因为只讨论奇数,所以可能i=n或者n-1反正只会进来一次无所谓了。最后一个元素不要空格。是否换行由t的值来判定。
           else if (p.size() - q.size() == -1 && (i == n || i == n - 1)) { cnt++; printf("%d", q.top()); }
       }
       if (t > 0)printf("\n");//如果不是最后一次样例就换行,否则不要。
   }
   return 0;
}

写在最后:请不要喷我,我知道我代码真的又臭又长,跟那些大佬的优美代码仿佛不是一种语言,但我真的尽力了。缝缝补补地打补丁就是这样。。。

全部评论

相关推荐

点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务