拼不出的数
lost.in/.out/.cpp
【问题描述】
3 个元素的集合{5, 1,2} 的所有子集的和分别是0,1, 2, 3, 5, 6, 7, 8。发
现最小的不能由该集合子集拼出的数字是4。
现在给你一个n 个元素的集合,问你最小的不能由该集合子集拼出的
数字是多少。
注意32 位数字表示范围。

【输入格式】
第一行一个个整数n。
第二行n 个正整数ai,表示集合内的元素。
【输出格式】
一行一个个整数答案。

 

【样例输入】
3
5 1 2
【样例输出】
4
【数据规模和约定】
对于30% 的数据,满足n <=15。
对于60% 的数据,满足n <= 1000。
对于100% 的数据,满足n <= 100000; 1 <= ai <= 10^9。

 

题解:排序+前缀和

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<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;

int n,a[100008];
LL sum;

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++){
        if(a[i]>sum+1){
            printf("%lld\n",sum+1);
            return 0;
        }
        sum+=a[i];
    }
    printf("%lld\n",sum+1);
    return 0;
}
AC

相关文章:

  • 2022-12-23
  • 2021-07-22
  • 2022-12-23
  • 2021-05-02
  • 2022-12-23
  • 2022-02-19
  • 2021-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-06-01
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案