題面
題解
好久沒有更博客了啊。。
這題,官方題解似乎炸了,403了,網上也沒有找不到
那就來填一下坑吧
當然,可能寫得不是很嚴謹。。那大家就感受一下?
首先,通過玩樣例二,我們可以發現,如果說,我們存在一箇中間的數,他出現了兩次或以上,那麼我們顯然就讓他一直作爲中位數是最優的,然後填數一定是一小一大,一小一大這麼填。你會發現,在這種情況下,這個填數方案是最優的。
因爲要字典序最大,因此,我們一定希望前面的人最大
先考慮一下沒有相同的數怎麼做
容易發現這麼一個結論,就是如果你當前的還沒有填的最小值比中位數要小
那麼你一定GG了
因爲你無論在什麼時候,填入這個最小值,他都會使得中位數變小
那麼就不難得到一個做法,就是我們在每一位填之前,尋找一個我們能填的最大的數,且滿足填了以後,最小的數還是不比中位數小的是什麼,這個用set就能解決了
至於怎麼維護中位數,我們可以維護兩個堆
然後,我們再來考慮一下有相同的數怎麼做?
如果相同的數,出現在中間數以後,也就是座標在以後,那麼他肯定是沒有用的。因爲最後的中位數一定比這些數小,因此,我們不可能存在一個時刻,使得這些數成爲中位數,那麼也就是他們是不是一樣的沒有任何影響,只是拿來湊數的,可以直接把他們看做不同的,並不會影響答案。
那麼,我們再考慮,如果這些數出現在中間數之前,那麼顯然地,我們可以讓前半段的中位數直接變成他。具體來說,就是我們找一個在最大的一個有重複數字的,然後和之前第一步那個一樣。先填兩個,然後一小一大,一小一大地填。
然後剩下的數,就是沒有重複的了
直接按照沒有相同的數來做就OK了
接着這題就做完了,代碼也挺好寫的
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<set>
#include<queue>
using namespace std;
const int N=100005;
int A[N];
int n;
bool ok[N];//這個點用了沒
priority_queue<int> a,b;
void Push (int x)
{
if (a.empty()||x<=a.top()) a.push(x);
else b.push(-x);
if (a.size()<b.size()) {int x=b.top();b.pop();a.push(-x);}
if (a.size()>b.size()+1) {int x=a.top();a.pop();b.push(-x);}
}
multiset<int> s;
multiset<int>::iterator it;
int main()
{
scanf("%d",&n);
for (int u=1;u<=n;u++) scanf("%d",&A[u]);
sort(A+1,A+1+n);int mid=(n+1)>>1;
if (A[mid]==A[mid+1])
{
while (A[mid]==A[mid+1]) mid++;
printf("%d ",A[mid]);
int p=n,q=mid-1;
while (p>mid||q>0)
{
if (q>0) printf("%d ",A[q--]);
if (p>mid) printf("%d ",A[p--]);
}
return 0;
}
memset(ok,false,sizeof(ok));
while (mid>1&&A[mid-1]!=A[mid]) mid--;
ok[mid]=true;
printf("%d ",A[mid]);
int p=n,q=mid-1;
while (p>mid&&q>0)
{
ok[q]=true;printf("%d ",A[q--]);
ok[p]=true;printf("%d ",A[p--]);
}
for (int u=1;u<=n;u++)
{
if (ok[u]) Push(A[u]);
else s.insert(A[u]);
}
while (!s.empty())
{
int x=*s.begin();
int ans;
if (a.size()==b.size())//加入這個數以後是變成單個數的
{
if (x>=(-b.top())) ans=*(--s.end());
else ans=x;
}
else//變成平均數的
{
if (!b.empty()&&(x*2>=a.top()-b.top())) ans=*(--s.end());
else
{
ans=*(--s.upper_bound(x*2-a.top()));
}
}
printf("%d ",ans);
Push(ans);s.erase(s.find(ans));
}
return 0;
}