题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6557
参考题解:https://blog.csdn.net/qq_41289920/article/details/101170629
题意:给定n个数,
表示数
,判断是否存在一个分配方案,将这n个数,分成2堆,使得每堆数之和都大于1/2。
题解:巧用set,保存当前凑出的数中,是否达到了1/2。利用好一点,2个k+1,得到一个k。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=200010;
struct node{
int val,id;
bool operator <(const node &b) const{
return val<b.val;
}
}h[maxn];
int n;
int ans[maxn];
unordered_map<int,int> mp;
//map<int,int> mp;
int main(){
int t,cas=1;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&h[i].val);h[i].id=i;
ans[i]=0;
}
sort(h+1,h+n+1);
mp.clear();
int pos=-1;
printf("Case %d: ",cas++);
for(int i=1,val;i<=n;i++){
val=h[i].val;
while(mp[val]&&val>=2) mp[val]=0,val--;
mp[val]=1;
if(val==1){
pos=i+1;break;
}
}
if(pos==-1){
puts("NO");continue;
}
int mx=1000000000;
mp.clear();
for(int i=pos,val;i<=n;i++){
val=h[i].val;
ans[h[i].id]=1;
while(mp[val]&&val>=2) mp[val]=0,val--;
mp[val]=1;
if(val==1){
pos=mx;break;
}
}
if(pos!=mx){
puts("NO");
}else{
puts("YES");
for(int i=1;i<=n;i++) putchar('0'+ans[i]);
puts("");
}
}
return 0;
}