Description
今天是校赛的日子,为了庆祝这么喜庆的日子,TMK打算买些礼物给女票LSH庆祝一下。
TMK进入了雪梨超市,然后刚踏入的一瞬间,店主就对TMK说:“恭喜你成为了本店第2147483647位顾客,本店在搞一个活动,对本店第2147483647位顾客进行赠送活动。你先看看你有多少钱?”
TMK一摸口袋,发现只有n个硬币,每个硬币的价值为a[i]。
然后店主继续说:“现在你用你的钱凑一些数,如果你的钱能凑成[0,x]里面所有的数,那么你将会免费获得该店价值x元的代金券,假设你有四个硬币面值分别为1,2,4,100,你就可以凑成[0,7]里面所有的数,我们将会送你7元的代金券。现在就用你的硬币来试试吧。Enjoy yourself!”
在TMK努力凑钱的时候,店主想知道他要送多少代金券给TMK。
Input
第一行一个整数T,表示数据组数。
对于每组数据,首先读入一个整数n(n<=100000),然后接下来的一行有n个整数,表示a[i](0<a[i]<=1e9)
Output
对于每个数据,输出一个整数x,表示店主要送x元的代金券给TMK
Sample Input
1 3 1 2 3
Sample Output
6
HINT
官方题解:
首先,先对 a[i]从小到大排序,假设对于前 i 个硬币,我们可以组合成 0~y:
①如果 a[i+1]>y+1,那么从 i+1~n 中任意取硬币,构成的和都>y+1,所以必定构造不出
y+1,于是答案等于 y。
②如果 a[i+1]<=y+1,那么前 i+1 位可以组合成 0~y+a[i+1]。
所以只需要对硬币从小到大排序,然后从第一个硬币枚举到最后一个硬币,或者中途有
某个数够不出来即可得到答案。
要注意,输出要用long long型,否则会溢出!
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #define MAX 100005 6 typedef long long ll; 7 using namespace std; 8 int N,T; 9 int v[MAX]; 10 bool check(ll n,ll sum) 11 { if(v[n]>sum+1) return false; 12 else return true; 13 } 14 int main() 15 { cin>>T; 16 while(T--){ 17 cin>>N; 18 for(int i=0;i<N;i++) scanf("%d",&v[i]); 19 stable_sort(v,v+N); 20 ll ans=0; 21 for(int i=0;i<N;i++){ 22 if(check(i,ans)) ans+=v[i]; 23 else break; 24 } 25 cout<<ans<<endl; 26 } 27 return 0; 28 }