大致题意:给你一个n个元素的集合,问你最小的不能由该集合子集拼出的数字是多少
思路- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
排序+前缀和
核心语句:if(a[i]>sum+1)cout<<sum+1,return 0;
原理:
sum表示当前前缀和
如果当前加入的数大于前缀和+1,那么输出前缀和+1,否则继续。
因为需要表示连续的整数,那么相邻的数最多只能差1.
如果排序后k前面的数字之和<k-1,那么k-1这个数就无法表示。
再详细的说就是
现在能表示出[0,0]这个区间,那么对于排序后接下来的数k,如果k>1,那么1
这个数就永远也拼不出来。那么对于之前能拼出的区间为[0,x],加上k之后能拼出
的数至少为[k,x+k],必须要求[0,x]这个区间的右端点和[k,k+x]的左端点连续才能把所有
数都拼出来,也就是k<=x+1。
代码:- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#include <bits/stdc++.h>// 排序 + 前缀和 #define ll long long using namespace std; ll n,sum=0,a[100010];//sum为上一个前缀和 int main(){ cin>>n; for(ll i=1;i<=n;i++)cin>>a[i]; sort(a+1,a+n+1); for(ll i=1;i<=n;i++){ if(a[i]>sum+1){//说明 sum+1不能被拼出 cout<<sum+1<<endl; return 0; } sum+=a[i];//当前前缀和 } cout<<sum+1;//如果运行到这里,说明 1~sum的数都能被拼出 }
注意:int会爆,要用 long long