输入第一行为数字个数n (n ≤ 20) 第二行为n个数xi (1 ≤ xi ≤ 100000)
输出最小不能由n个数选取求和组成的数
3 5 1 2
4
//将数组vec所有元素排序,比如:1,2,5,6...
//前i-1个元素的和sum,初始值设为0,每次判断sum+1与第i个元素的大小关系
//(sum+1与vec[i]),若sum+1<vec[i],说明sum与vec[i]之间出现了断裂,sum+1
//即为最小的断裂元素(不可能由前面的元素组合成)。
//比如当i=2时,sum=vec[0]+vec[1]=1+2=3,则0~3是可以连续取到的,而此时sum+1<5,
//即3~5之间出现了断裂,4是取不到的。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
vector<int> vec;
for(int i=0;i<n;i++)
{
int number;
cin>>number;
vec.push_back(number);
}
sort(vec.begin(),vec.end());
long long sum=0;
int i;
for(i=0;i<n;i++)
{
if(sum+1<vec[i])
break;
sum+=vec[i];
}
cout<<sum+1<<endl;
}
} #include<stdio.h>
#include<string.h>
int a[25],book[2000005];
int main(){
int N,i,j;
//freopen("input.txt","r",stdin);
while(scanf("%d",&N)!=EOF){
memset(book,0,sizeof(book));
for(i=0;i<N;i++) scanf("%d",&a[i]);
for(i=0;i<1<<N;i++){
int res=0;
for(j=0;j<N;j++)
if(i>>j&1) res+=a[j];
book[res]=1;
}
for(i=1;i<=2000000;i++)
if(book[i]==0) break;
printf("%d\n",i);
}
}//这么小的数据,直接枚举所有子集就可以啦~ import java.util.*;
public class Main{
public static int minNum(int[] num){
Arrays.sort(num);
int number=1;
if(num[0]!=1){
return 1;
}
if(num.length==1){
return num[0]+1;
}
else{
for(int i=1;i<num.length;i++){
if(num[i]-number>1){
break;
}
else{
number+=num[i];
}
}
}
return number+1;
}
public static void main(String[] args){
Scanner s=new Scanner(System.in);
while(s.hasNext()){
int n=s.nextInt();
int num[]=new int[n];
for(int i=0;i<n;i++){
num[i]=s.nextInt();
}
System.out.println(minNum(num));
}
}
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine().trim());
String[] strArr = br.readLine().split(" ");
int[] arr = new int[n];
for(int i = 0; i < n; i++) arr[i] = Integer.parseInt(strArr[i]);
System.out.println(solve(arr));
}
private static int solve(int[] arr) {
Arrays.sort(arr);
if(arr[0] > 1) return 1;
if(arr.length == 1) return arr[0] + 1;
int sum = arr[0];
for(int i = 1; i < arr.length; i++){
if(arr[i] > 1 + sum)
break;
else
sum += arr[i];
}
return sum + 1;
}
} 先排序
a1 a2 .... an 升序
首先若a1!=1,那么最小不能组合的数为1
否则
sum(1)=a1表示前1个数之和,且sum(1)之内的数都可组合得到
设sum(i)为前i个数之和,且sum(i)之内的数都可以组合得到
则对于sum(i+1)而言
若a(i+1)-sum(i)>1,则表示前i个数之和小于a(i+1),也就是说前i个数无法组合成a(i+1)-1,
也就是说sum(i)和a(i+1)之间必有不能组合的整数,且最小为sum(i)+1;则找到不能组合的最小的数
若a(i+1)-sum(i)<=1,则sum(i+1)之内的任何数字都可以组合得到因为sum(i)之内的任何数可以得到且ai+1可以得到
如此递推下去
public static void main(String[] args)throws Exception{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(br.readLine());
int x[]=new int[n];
String[] strs=br.readLine().split(" ");
for(int i=0;i<n;i++){
x[i]=Integer.parseInt(strs[i]);
}
//排序
Arrays.sort(x);
if(x[0]>1){
System.out.println(1);
return;
}
int sum=0;
for(int i=0;i<n-1;i++){
sum+=x[i];
if(x[i+1]-sum>1){
System.out.println(sum+1);
return;
}
}
System.out.println(sum+x[n-1]+1);
}
while True:
try:
num,digitList = int(input()),list(map(int,input().split()))
digitList.sort()
pieceNum = 0 #表示此前已经可以拼凑前pieceNum的数了
for i in digitList:
if pieceNum+1 >= i: #如果当前i比pieceNum+1还要大,则这些数凑不出pieceNum+1
pieceNum += i #此时能凑的最大数为pieceNum+i
else:
print(pieceNum+1)
break
else:
print(pieceNum+1)
except Exception:
break
import java.util.*;
//先排序,记录可以累加到的和在map中,按顺序遍历,一旦出现空缺元素那就是不能累加到的第一个元素
public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
int n = Integer.parseInt(line);
line = scanner.nextLine();
String []s = line.split(" ");
int []arr = new int[n];
for (int i = 0;i < n;i ++) {
arr[i] = Integer.parseInt(s[i]);
}
System.out.println(min(arr));
}
public static int min(int []arr) {
Arrays.sort(arr);
if (arr[0] != 1) {
return 1;
}
int max = arr[0];
LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
Set<Integer> set = map.keySet();
for (int i = 0;i < arr.length;i ++) {
if (arr[i] - max > 1)return max + 1;
List<Integer> list = new ArrayList<>();
for (int j : set) {
list.add(j + arr[i]);
max = Math.max(max, j + arr[i]);
}
for (int num : list) {
map.put(num, 1);
}
map.put(arr[i], 1);
}
return max + 1;
}
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int n; cin>>n;
vector<int> data; int tmp;
for(int i=0; i<n; i++){cin>>tmp; data.push_back(tmp);}
sort(data.begin(), data.end());
if(data[0]!=1){cout<<1<<endl; return 0;}
int res = 1;
for(int i=1; i<data.size(); i++){
if(data[i]<=res+1) res+=data[i];
if(data[i]>res+1) break;
}
cout<<res+1<<endl;
return 0;
}
#include <iostream>
#include <vector>
#include <map>
#include <numeric>
#include <limits>
using namespace std;
/*参考了 牛客470556号 的思想
有数列a1~an升序排列
设a1~ai 可以组成数字 1~m
则a(i+1)-1<=m
因为a1~a(i+1)即a1~ai~a(i+1),显然可以组成{a(i+1)、a(i+1)+1、a(i+1)+2、...、a(i+1)+m}中任意一个数,最小的就是a(i+1)
所以a(i+1)不能大于(m+1),否则就会出现空档,即无法组成的数字
*/
int main() {
int n;
cin >> n;
map<int, int> m;
for(int i=0;i<n;i++)
{
int tmp;
cin >> tmp;
m[tmp] += 1;
}
map<int, int>::iterator it = m.begin();
int max;
if (it->first > 1)
max = 0;
else
{
max = (it->first)*(it->second);
for (it++; it != m.end(); it++)
{
if (max >= ((it->first) - 1))
max += (it->first)*(it->second);
else
break;
}
}
cout << ++max;
return 0;
} #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int i,j,n,temp;
vector<int> v;
cin>>n;
for(i=0;i<n;i++){
cin>>temp;
v.push_back(temp);
}
sort(v.begin(),v.end());
long long int sum=0;
for(j=0;j<v.size();j++){
if(v[j]>sum+1){
break;
}else{
sum+=v[j];
}
}
cout<<sum+1<<endl;
return 0;
} //最笨的方法,把所有的和计算出来,然后不能求和的
// 注意:相同的数字的处理
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc= new Scanner(System.in);
while(sc.hasNext()){
int n = sc.nextInt();
int[] num = new int[n];
int sum = 0;
for(int i=0;i<n;i++){
num[i] = sc.nextInt();
sum += num[i];
}
boolean[] s = new boolean[sum+1];
boolean flag = false;
for(int i=0;i<n;i++){
if(s[num[i]]){
flag = true;
}else{
s[num[i]] = true;
}
for(int j=sum;j>=0;j--){
if(flag){
if(s[j])s[j+num[i]]=true;
}else{
if(j!=num[i] && s[j])s[j+num[i]]=true;
}
}
flag = false;
}
flag = false;
int min = 1;
for(;min<=sum;min++){
if(!s[min]){
break;
}
}
if(min==sum+1){
System.out.println(sum+1);
}else{
System.out.println(min);
}
}
}
} import java.util.Scanner;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
//输入
Scanner sc = new Scanner(System.in);
int count = sc.nextInt();
int[] nums = new int[count];
for (int i = 0; i < count; i++) {
nums[i] = sc.nextInt();
}
//排序
Arrays.sort(nums);
//特例,没有1直接输出1
if (nums[0] > 1) {
System.out.println(1);
return;
}
//依次求和
int sum = 0;
for (int i = 0; i < count - 1; i++) {
sum += nums[i];
if (sum + 1 < nums[i + 1]){
System.out.println(sum + 1);
return;
}
}
System.out.println(sum + nums[count - 1] + 1);
}
} #include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <algorithm>
using namespace std;
typedef long long ll;
int a[1005];
int main(){
int miss=0;
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
sort(a,a+n);
for(int i=0;i<n;i++){
if(a[i]>miss+1) break;
miss+=a[i];
}
printf("%d\n",miss+1);
return 0;
}
//对于从小到到排序的数列arr,前k项之和为sum,则1~sum都可以用前k项表示(取其中的某几个相加)
//如果arr[k+1]<=sum+1 ,则 1~sum+arr[k+1] 可以用前 k+1 个数字表示
var readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
var countLine = 1;
var tokens = [];
rl.on('line', function(line){
tokens.push(line);
if(countLine == 2){
var n = parseInt(tokens[0]);
var arr = tokens[1].split(' ').map(function(item){
return parseInt(item);
});
var sum = 0;
arr.sort(function(value1, value2){
return value1 - value2;
});
for(var i=0; i<n; i++){
if(arr[i]> sum+1)
break;
sum += arr[i]; //前i项和
}
console.log(sum+1);
}else{
countLine++;
}
});