zoukankan      html  css  js  c++  java
  • #280. 【UTR #2】题目难度提升

    题目描述

    最终吉米多出题斯基没有找到优质的题目,于是高产的吉米多出题斯基决定自己出一道。

    首先,吉米多出题斯基脑洞了一道难度为 h1 的题目,然而吉米多出题斯基觉得太水了,于是把这题稍微改了改变成了一道难度为 h2 的。然而吉米多出题斯基还是觉得太水了,又稍微改了改变成了难度为 h3 的。如此进行下去吉米多出题斯基脑洞出了 n 个版本的题目,难度分别为 h1,…,hn。

    由于吉米多出题斯基在脑洞的时候只是随便改了改题目条件,所以每次改题并不一定会变难。但神奇的是,每次产生一个新版本的题目后,吉米多出题斯基手上所有版本的题目难度的中位数不会降低。

    很快吉米多出题斯基出好了题,造好了 UOI,选手们纷纷阵亡。多年后吉米多出题斯基再看到自己曾经出的这道题时感叹道:“都是回忆啊……”

    可是吉米多出题斯基突然发现自己只记得脑洞过程产生的 n 个版本难度是 a1,…,an,却不记得每个 ai 对应的是第几个版本了。

    吉米多出题斯基日理万机没有时间再细想了,于是他找到了你 —— 风璃殇做不出题耶维奇,请你帮助吉米多出题斯基把 a1,…,an 排列顺序,给出一组满足条件且字典序最大的 h1,…,hn 吧!

    对于一个数列 v1,…,vm,若 m 为奇数则定义中位数为从小到大第 ⌈m/2⌉ 的数;若 m 为偶数则定义中位数为从小到大第 m/2 和第 m/2+1 的数的平均值。

    输入格式

    第一行一个正整数 n。

    接下来一行 n 个整数 a1,…,an。

    输出格式

    一行,n 个整数表示你找到的字典序最大的 h1,…,hn。

    如果无解,输出卖萌表情 "QwQ"。

    样例一

    input

    5
    1 2 3 4 5

    output

    1 3 2 5 4

    explanation

    中位数依次为:{1,2,2,2.5,3}。

    样例二

    input

    8
    1 2 2 3 3 3 4 4

    output

    3 3 4 3 4 2 2 1

    样例三

    见样例数据下载。

    限制与约定

    子任务 分值 n 其他约定
    1 10 1≤n≤10 无
    2 10 1≤n≤100 无
    3 20 1≤n≤2000 无
    4 30 1≤n≤105 ai 互不相同
    5 30 1≤n≤105 无
    对于所有数据,满足 1≤ai≤109。

    时间限制:1s
    空间限制:256MB

    对顶堆

    这是一个大型分类讨论现场。。。
    讲a 从小到大排序

    a[mid] = a[mid+1]
    那么左一个右一个直接选完,即可得到最优解。

    否则 往左扫,直到扫到有挨着相同的。
    也是左一个右一个,但是肯定有剩余。
    把已经选了的放入(对顶)堆里,维护中位数
    没选的放入multiset中。
    分类讨论即可。。。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<bitset>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    typedef long long LL;
    const int N = 1e5+10;
    inline int read()
    {
        register int x = 0 , f = 0; register char c = getchar();
        while(c < '0' || c > '9') f |= c == '-' , c = getchar();
        while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0' , c = getchar();
        return f ? -x : x;
    }
    int n;
    int a[N] , vis[N];
    priority_queue<int> A , B;
    multiset<int> s;
    
    void push(int x)
    {
    	if(A.empty() || x <= A.top()) A.push(x); else B.push(-x);
    	if(A.size() < B.size()) A.push(-B.top()) , B.pop();
    	if(A.size() - 1 > B.size()) B.push(-A.top()) , A.pop();
    	return ;
    }
    
    void solve()
    {
    	sort(a + 1 , a + 1 + n); int mid = (n + 1) >> 1;
    	if(a[mid] == a[mid + 1])
    	{
    		while(mid < n && a[mid] == a[mid + 1]) mid++;
    		cout << a[mid] << ' '; int p = mid - 1 , q = n;
    		while(p || q > mid)
    		{
    			if(p) cout << a[p--] << ' ';
    			if(q > mid) cout << a[q--] << ' ';
    		}
    		cout << '
    '; return ;
    	}
    	while(mid > 1 && a[mid] != a[mid - 1]) mid--;
    	vis[mid] = 1; cout << a[mid] << ' '; int p = mid - 1 , q = n;
    	while(p && q > mid) cout << a[p] << ' ' , vis[p--] = 1 , cout << a[q] << ' ' , vis[q--] = 1;
    	for(int i = 1 ; i <= n ; ++i) if(!vis[i]) s.insert(a[i]); else push(a[i]);
    	while(!s.empty()) // 满足堆里的中位数 <= 没选的的最小值 
    	{
    		int p = *s.begin() , q;
    		if(A.size() == B.size())
    		{
    			if(p >= -B.top()) q = *--s.end();  // 最小值比中位数大。怎么选也合法,选最大的字典序更大 
    			else q = *s.begin(); // 再不选那个*s.begin就 < 堆中的最小值。 
    		}
    		else
    		{
                if(!B.empty() && p * 2 >= A.top() - B.top()) q = *--s.end(); // 同上 
                else q = *--s.upper_bound(p * 2 - A.top()); // 偶数时不一定选他自己,可以选中间两个数的中间的数,比如2 , 10 , 可以不选3,选6, 3可以之后再选 
    		}
    		cout << q << ' '; s.erase(s.find(q)); push(q); // s.erase(find(q)) 是只删一个 
    	}
    	return ;
    }
    
    int main()
    {
    	freopen("c.in" , "r" , stdin);
    	freopen("c.out" , "w" , stdout);
    	n = read();
    	for(int i = 1 ; i <= n ; ++i) a[i] = read();
    	solve();
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    /*
    10
    1 2 2 3 3 3 4 4 5 6
    */
    
  • 相关阅读:
    Clean Docker <none>:<none>
    Conservation Vs Non-conservation Forms of conservation Equations
    What are the differences between an LES-SGS model and a RANS based turbulence model?
    How to permanently set $PATH on Linux/Unix?
    tar解压命令
    C++ (P199—P211)多态 虚函数 抽象类
    C++ (P160—)多继承 二义性 虚基类 “向上转型”
    java与c++的访问权限的问题
    由strupr,strlwr体会如果将字符常量转换为变量进行修改,体会常量的静态存储
    C++ (P103—P154)
  • 原文地址:https://www.cnblogs.com/R-Q-R-Q/p/12681113.html
Copyright © 2011-2022 走看看