ZOJ 4102 2019浙江省赛C题 Array in the Pocket

首先set贪心取最小,但是没填入B集合里的个数最多的元素加上A集合中待填的该元素,不可多于剩下的元素数,否则要取该元素。
1 1 2 2 3 3 3
2
如果第二个元素填2 则剩下的3的个数,加上A里的剩下的3的个数多于(6/2)(6是剩下的元素个数)
所以第二个元素只能填3
当然,如果一开始就有元素多于n/2,输出Impossible.

#include<bits/stdc++.h>
using namespace std;
const int M=1e5+10;
int a[M],b[M];
int c[M],cc[M];
typedef pair<int,int> P;
set<P> s1,s2;
set<P>::iterator it,mx;
int main(){
	int t,n;
	cin>>t;
	while(t--){
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			a[i]=b[i]=c[i]=cc[i]=0;
		}
		s1.clear();s2.clear();
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			c[a[i]]++;cc[a[i]]+=2;
			
		}
		for(int i=1;i<=n;i++){
			if(c[i]){
				s1.insert(P(i,c[i]));
			    s2.insert(P(cc[i],i));
			}
			
		}
		//int temp=(*(--s2.end()))->first;
		it=s2.end();
		it--;
		int temp=it->first;
		if(temp>n){
			printf("Impossible\n");
			continue;
		}
		
		for( int i=1;i<=n;i++){
			s2.erase(P(cc[a[i]],a[i]));
			s2.insert(P(--cc[a[i]],a[i]));
			 it=s1.begin();
			 mx=s2.end();
			 mx--;
			if(mx->first==n-i+1){
				b[i]=mx->second;
			}
			else {
				if(a[i]==it->first)it++;
				b[i]=it->first;
			}
			s1.erase(P(b[i],c[b[i]]));
			c[b[i]]--;
			s2.erase(P(cc[b[i]],b[i]));
			cc[b[i]]--;
			if(c[b[i]])s1.insert(P(b[i],c[b[i]]));
			if(cc[b[i]])s2.insert(P(cc[b[i]],b[i]));
		}
		cout<<b[1];
		for(int i=2;i<=n;i++){
			printf(" %d",b[i]);
		}
		printf("\n");
	}
}
发布了18 篇原创文章 · 获赞 9 · 访问量 899

猜你喜欢

转载自blog.csdn.net/weixin_42859385/article/details/90082549