Running Median POJ

For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output the median (middle value) of the elements received so far.

Input

The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets that follow. The first line of each data set contains the data set number, followed by a space, followed by an odd decimal integer M, (1 ≤ M ≤ 9999), giving the total number of signed integers to be processed. The remaining line(s) in the dataset consists of the values, 10 per line, separated by a single space. The last line in the dataset may contain less than 10 values.

Output

For each data set the first line of output contains the data set number, a single space and the number of medians output (which should be one-half the number of input values plus one). The output medians will be on the following lines, 10 per line separated by a single space. The last line may have less than 10 elements, but at least 1 element. There should be no blank lines in the output.

Sample Input

3 
1 9 
1 2 3 4 5 6 7 8 9 
2 9 
9 8 7 6 5 4 3 2 1 
3 23 
23 41 13 22 -3 24 -31 -11 -8 -7 
3 5 103 211 -311 -45 -67 -73 -81 -99 
-33 24 56

Sample Output

1 5
1 2 3 4 5
2 5
9 8 7 6 5
3 12
23 23 22 22 13 3 5 5 3 -3 
-7 -3

题意:每组M个数,然后对于每组数读入的时候,只要读入了奇数个的数,就求出先前读入数的中位数,然后输出

思路:可以采用两个优先队列的做法,如果当前读入的数>当前中位数,插入小根堆,否则插入大根堆,这样实际上就维护了中位数相邻两侧的值。
然后维护 num【小根堆】 - num【大根堆】 <= 1,就是维护中位数两侧的数量应当均分,这样小根堆的top,即是中位数

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<queue>
 4 using namespace std;
 5 
 6 int t;
 7 int cas,n;
 8 const int maxn = 1e4+5;
 9 int ans[maxn];
10 int main()
11 {
12     scanf("%d",&t);
13     while(t--)
14     {
15 priority_queue<int,vector<int>,greater<int> >que1;
16 priority_queue<int,vector<int>,less<int> >que2;
17 
18         scanf("%d%d",&cas,&n);
19         printf("%d %d
",cas,n/2+1);
20         int tmp;
21         int l=0,r=0,num=0;
22         int cnt = 0;
23         for(int i=1;i<=n;i++)
24         {
25             scanf("%d",&tmp);
26             if(tmp > num)
27             {
28                 que1.push(tmp);
29                 r++;
30             }
31             else
32             {
33                 que2.push(tmp);
34                 l++;
35             }
36             if(r < l)
37             {
38                 int f = que2.top();
39                 que2.pop();
40                 que1.push(f);
41                 r++,l--;
42             }
43             else if(r > l + 1)
44             {
45                 r--,l++;
46                 int f = que1.top();
47                 que1.pop();
48                 que2.push(f);
49             }
50             num = que1.top();
51             if(i&1)
52             {
53                 ans[++cnt] = num;
54             }
55         }
56         for(int i=1;i<=cnt;i++)
57         {
58             printf("%d",ans[i]);
59             if(i != cnt && i%10!=0)printf(" ");
60             else printf("
");
61         }
62     }
63 }
View Code
链表:
链表主要是个离线处理,先将所有的数据读入,然后记录下其下标。
然后对其排序,记录下在有序序列下,原来下标的数在哪出现。
然后从n~1进行处理,因为n永远是该序列剩余的数中最后出现的,也就是说不会将该数后未输入的数进行计算。

(关于中位数下标pos的移动那,按照写法是有问题的,但是这题上适用)
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int t;
int cas,n;
const int maxn = 1e4+5;
struct Node
{
    int val;
    int next;
    int pre;
    int index;
}node[maxn];
int p[maxn];

bool cmp(Node a,Node b)
{
    return a.val < b.val;
}
int ans[maxn];
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&cas,&n);
        printf("%d %d
",cas,(n+1)>>1);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&node[i].val);
            node[i].index = i;
        }
        sort(node+1,node+1+n,cmp);
        for(int i=1;i<=n;i++)
        {
            node[i].next = i+1;
            node[i].pre = i-1;
        }
        node[1].pre = node[n].next = -1;
        for(int i=1;i<=n;i++)
        {
            p[node[i].index] = i;
        }
        int pos = (n+1)>>1;
        int tot = 0;
        int l=0,r=0;
        for(int i=n;i>0;i--)
        {

            if(i & 1)
            {
                if(l  > r)pos = node[pos].next;
                else if(l < r)pos = node[pos].pre;
                ans[++tot] = node[pos].val;
                l=r=0;
            }
            if(p[i] >= pos)r++;
            if(p[i] <= pos)l++;
            if(node[p[i]].pre != -1)
            {
                node[node[p[i]].pre].next = node[p[i]].next;
            }
            if(node[p[i]].next != -1)
            {
                node[node[p[i]].next].pre = node[p[i]].pre;
            }
        }
        for(int i=1;i<=tot;i++)
        {
            printf("%d",ans[tot-i+1]);
            if(i%10 != 0 && i != tot)printf(" ");
            else printf("
");
        }
    }
}
View Code


原文地址:https://www.cnblogs.com/iwannabe/p/10165305.html