Median(vector+二分)

Median


Time Limit: 5 Seconds Memory Limit: 65536 KB



The median of m numbers is after sorting them in order, the middle one number of them if m is even or the average number of the middle 2 numbers if m is odd. You have an empty number list at first. Then you can add or remove some number from the list.

For each add or remove operation, output the median of the number in the list please.

Input

This problem has several test cases. The first line of the input is an integer T (0<T<=100) indicates the number of test cases. The first line of each test case is an integer n (0<n<=10000) indicates the number of operations. Each of the next n lines is either "add x" or "remove x"(-231<=x<231) indicates the operation.

Output

For each operation of one test case: If the operation is add output the median after adding x in a single line. If the operation is remove and the number x is not in the list, output "Wrong!" in a single line. If the operation is remove and the number x is in the list, output the median after deleting x in a single line, however the list is empty output "Empty!".

Sample Input

2
7
remove 1
add 1
add 2
add 1
remove 1
remove 2
remove 1
3
add -2
remove -2
add -1

Sample Output

Wrong!
1
1.5
1
1.5
1
Empty!
-2
Empty!
-1

Hint

if the result is an integer DO NOT output decimal point. And if the result is a double number , DO NOT output trailing 0s.

题意:找中位数,由于数据比较大,用到了vector容器,

我也不会用,比赛前看过一点,可是不知道怎么用,so。。。比赛完,借大神的代码来观摩下,哈哈。我发现这个真的很好用。我一定要把他学会!!!

ps:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4736

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
vector<int>vet;
int deal(int x)
{
    int left=0,right=vet.size()-1;
    while(left<=right)
    {
        int mid=(left+right)/2;
        if(vet[mid]==x)
        {
            return mid;
        }
        else if(vet[mid]>x)
        {
            right=mid-1;
        }
        else
        {
            left=mid+1;
        }
    }
    return -1;
}
int erfen(int x)
{
    if(vet.size()==0) return 0;
    if(x<vet[0]) return 0;
    if(x>vet[vet.size()-1]) return vet.size();
    int left=0,right=vet.size()-1,k=-1;
    while(left<=right)
    {
        int mid=(left+right)/2;
        if(vet[mid]>=x&&vet[mid-1]<=x)
        {
            return mid;
        }
        else if(vet[mid]<=x&&vet[mid+1]>=x)
        {
            return mid+1;
        }
        else if(vet[mid]>x)
        {
            right=mid-1;
        }
        else left=mid+1;
    }
}
int main()
{
    int text;
    scanf("%d",&text);
    while(text--)
    {
        int n;
        scanf("%d",&n);
        vet.clear();
        vector<int>::iterator it=vet.begin();
        while(n--)
        {

            char ch[30];
            int x;
            scanf("%s%d",ch,&x);
            if(ch[0]==‘r‘)
            {
                if(vet.size()==0)
                {
                    printf("Wrong!\n");
                    continue;
                }
                else
                {
                    int tmp=deal(x);
                    if(tmp==-1)
                    {
                        printf("Wrong!\n");
                        continue;
                    }
                    else
                    {
                        it=vet.begin();
                        vet.erase((it+tmp));
                        int len=vet.size();
                        if(len==0)
                        {
                            printf("Empty!\n");
                            continue;
                        }
                        else if(len%2==1)
                            cout<<vet[len/2]<<endl;
                        else
                        {
                            long long ans=(long long)vet[len/2]+(long long)vet[len/2-1];
                            if(ans%2==0)
                                printf("%lld\n",ans/2);
                            else
                            {
                                double sum=ans/2.0;
                                printf("%.1lf\n",sum);
                            }
                        }

                    }
                }
            }
            else
            {
                int tmp=erfen(x);
                it=vet.begin();
                vet.insert((it+tmp),x);
                int len=vet.size();
                if(len%2==1)
                    printf("%d\n",vet[len/2]);
                else
                {
                    long long ans=(long long)vet[len/2]+(long long)vet[len/2-1];
                    if(ans%2==0)
                        printf("%lld\n",ans/2);
                    else
                    {
                        double sum=ans/2.0;
                        printf("%.1lf\n",sum);
                    }
                }
            }
        }
    }
    return 0;
}

加油!!!加油!!!

时间: 2024-10-02 10:58:09

Median(vector+二分)的相关文章

【POJ - 3579 】Median(二分)

Median Descriptions 给N数字, X1, X2, ... , XN,我们计算每对数字之间的差值:∣Xi - Xj∣ (1 ≤ i < j ≤N). 我们能得到 C(N,2) 个差值,现在我们想得到这些差值之间的中位数. 如果一共有m个差值且m是偶数,那么我们规定中位数是第(m/2)小的差值. Input 输入包含多测每个测试点中,第一行有一个NThen N 表示数字的数量.接下来一行由N个数字:X1, X2, ... , XN( Xi ≤ 1,000,000,000  3 ≤

【cf1285E】E. Delete a Segment(vector+二分)

传送门 题意: 给出\(n\)个区间,最终区间会合并为多个块. 现在要删除一个区间,问最终剩下的块最多是多少个. 思路: 将区间按左端点排序后,考虑维护区间的前后缀,然后枚举要删除的区间: 处理起来较麻烦,且维护的信息很多: 所以直接维护前缀信息,然后倒着来枚举删除区间,同时动态维护后缀: 统计答案时需要在后缀区间中二分,时间复杂度为\(O(nlogn)\). 细节见代码: /* * Author: heyuhhh * Created Time: 2020/1/27 10:21:46 */ #i

POJ 3579 Median(二分答案+Two pointers)

[题目链接] http://poj.org/problem?id=3579 [题目大意] 给出一个数列,求两两差值绝对值的中位数. [题解] 因为如果直接计算中位数的话,数量过于庞大,难以有效计算, 所以考虑二分答案,对于假定的数据,判断是否能成为中位数 此外还要使得答案尽可能小,因为最小的满足是中位数的答案,才会是原差值数列中出现过的数 对于判定是不是差值的中位数的过程,我们用尺取法实现. 对于差值类的题目,还应注意考虑边界,即数列只有一位数的情况. [代码] #include <cstdio

Vector求期末成绩

#include<iostream> #include <string> #include <stdexcept> #include <iomanip> #include <algorithm> #include <vector> using namespace std; //求排序后家庭作业成绩中的中间成绩 double median(vector<double> vec) { typedef vector<dou

HackerRank &quot;Median Updates&quot;

Same as LintCode "Sliding Window Median", but requires more care on details - no trailing zeroes. #include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <q

[LintCode] Median(期望时间复杂度O(n)求中位数)

1 class Solution { 2 public: 3 /** 4 * @param nums: A list of integers. 5 * @return: An integer denotes the middle number of the array. 6 */ 7 void swap(vector<int> &v, int i, int j) 8 { 9 int tmp = v[i]; 10 v[i] = v[j]; 11 v[j] = tmp; 12 } 13 i

[容易]中位数

题目来源:http://www.lintcode.com/zh-cn/problem/median/ C++版 VS2012测试通过 方法一 1 class Solution { 2 public: 3 /** 4 * @param nums: A list of integers. 5 * @return: An integer denotes the middle number of the array. 6 */ 7 int median(vector<int> &nums) {

THUSC 2016游记

又去北京转了一圈,拿到了很不错的协议,非常的开森 day -1 6.2 上午去pku的同学就走了QAQ 然后波哥说下午要考试,考联考题 我一脸无奈的表示我已经提前要到题目而且看了题了 然后波哥就决定给我单独换一套题,于是就发生了悲惨的故事 他给我换了一套Nescafe的题目! 结果下午被两道FFT和一道数论题拍了一脸懵逼 晚上一直在颓颓颓,搞定了BZOJ的一道数据结构题 一脸不情愿的去改Nescafe的题目(结果第二题貌似压位大法+O2就A掉了) 然后就很不想去改第二题(感觉每天暴力写写一副滚粗

《Accelerated C++》 笔记

<Accelerated C++> 笔记 书籍ISBN:978-7-111-22404-4 ? Chapter 8 P123 typename关键字 这里举了一个这样的例子: template <class T> T median (vector<T> v){ ???typedef typename vector<T>::size_type vec_sz; ???... } 对typename关键字的说明是:这里的typename是要告诉编译器,vector