*题目描述 *
这天,n 位小朋友聚在一起吹牛,他们每个人手里都有一定数量的小星星,为了方便统计,我们使用a 1 ,a 2 ,…,a n 来表示。
小小歪吹牛到,从我们几个人中挑出几个来,手里的小星星数量全部加起来,可以表示出 𝑛 n 以内的任意一个正整数!
小小龙认为小歪错了,但是他是小朋友,他不会计算。 所以小小龙来求助你,他想让你找到最小的整数证明小小歪是错误的。
示例1
输入
2
4
4 1 5 2
2
1 3
输出
Cool!
2
知识点:排序+贪心+前缀和
mp存储出现的数字。j表示1-n,计数用.
当前缀和减j的数在mp中出现就表示数组中能找到几个数相加等于j, 其实数组要是没有1这个是肯定不能满足要求的,因此我们可以提前设置mp[0]=1,mp[sum[i]-j]=1说明在mp中存在一个或几个数相加让sum[i]-x=j,
由于当前i的前缀和要是大于等于j(sum[i]-j>=0) 就是有可能前i项中有某几个数字和等于j.所以i不能跟着每次循环自增。
最后前面处理完之后,把此次能表示出来的数全部存储到mp容器中。
using namespace std;
#define int long long
#define endl '\n'
int sum[100010],a[100010];
unordered_map<int,int>mp;
int t,n,flag,ans,fl;
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
flag=0,ans=0,fl=0;
for(int i=1,j=1;i<=n;j++)
{
if(mp[sum[i]-j]!=1||mp[sum[i]-a[i]]!=1){
flag=j;
break;
}
mp[a[i]]=1;
mp[sum[i]]=1;
if(j==n){
fl=1;
break;
}
if(sum[i]<j+1) {
i++;
continue;
}
mp[j]=1;
}
if(fl) cout<<"Cool!"<<endl;
else cout<<flag<<endl;
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>t;
while(t--){
mp[0]=1;
solve();
mp.clear();
}
return 0;
}