首页 > 试题广场 >

数字游戏

[编程题]数字游戏
  • 热度指数:21290 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
小易邀请你玩一个数字游戏,小易给你一系列的整数。你们俩使用这些整数玩游戏。每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字。 例如: 如果{2,1,2,7}是你有的一系列数,小易说的数字是11.你可以得到方案2+2+7 = 11.如果顽皮的小易想坑你,他说的数字是6,那么你没有办法拼凑出和为6 现在小易给你n个数,让你找出无法从n个数中选取部分求和的数字中的最小数(从1开始)。

输入描述:
输入第一行为数字个数n (n ≤ 20)
第二行为n个数xi (1 ≤ xi ≤ 100000)


输出描述:
输出最小不能由n个数选取求和组成的数
示例1

输入

3
5 1 2

输出

4
分享个不太厉害的方法:
所有的数所有数可能组合的和 都扔进HashSet集合,i从1开始,如果 set.contains(i)为false,则就是所求的数,实现如下:
import java.util.HashSet;
import java.util.Scanner;

public class Main {
public static void main(String args[]){
HashSet<Integer> set = new HashSet<Integer>();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int [] arr = new int[n];
for(int i=0;i<n;i++){
arr[i]=sc.nextInt();
set.add(arr[i]);
}
int sum=0;// 0 个数组合相加的和为0
int index=0;//数组的第一个元素开始
int count=0;//当前已经有count个数相加,和为sum
fun(sum,index,arr,count,set);
int i=1;
while(true){
if(!set.contains(i)){
System.out.println(i);
break;
}
i++;
}
}
public static void fun(int sum,int index,int[] arr,int count,HashSet set){
//对于数组中的每个数 arr[index] 都有两种状态,加或不加
if(count!=0)//大于0个数相加,不管上一次sum有没有加arr[index],都将sum扔进set集合
set.add(sum);
if(index>=arr.length)//index>=arr.length说明上一次函数已经处理了数组最后一个元素
return;//所以结束
fun(sum,index+1,arr,count,set);//针对当前arr[index]这个数,sum不加,所以count不变
fun(sum+arr[index],index+1,arr,count+1,set);//sum加上当前这个arr[index],count+1
}
}
编辑于 2018-08-17 22:25:01 回复(0)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main {     public static void main(String[] args) throws NumberFormatException, IOException {         BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));         int n = Integer.parseInt(bf.readLine());         String[] s = bf.readLine().split(" ");         int[] x = new int[n];         for(int i = 0; i < n; i++)             x[i] = Integer.parseInt(s[i]);         Arrays.sort(x);         if(x[0]-1!=0){             System.out.println(1);         }else{             int[] dp = new int[n];             dp[0] = 1;             int i = 1;             for(; i < n; i++){                 if(dp[i-1]<x[i]-1) break;                 dp[i] = dp[i-1]+x[i];             }             System.out.println(dp[i-1]+1);         }     }

}
方法都差不多。dp[i]代表前i项所能表达的连续最大值。
若dp[i-1]>x[i],说明前i-1个数中一定有k个数项可以表示出1~x[i]的数值,用x[i]顶替这k个数项。
因此,若要求dp[i-1]+1~dp[i-1]+x[i]的数,则用x[i]代替原先用来求和的k个数项,多出来的k个数项就能在dp[i-1]的基础上+1~+x[i]了。
递推直至条件不成立。
发表于 2018-07-18 14:29:13 回复(0)
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;
    }
}

发表于 2018-05-21 18:47:59 回复(0)
//举个例子其实就明白了
/**
比如:1 2 3 4 12 --> 1+2+3+4=10 --> 10+1<12 --> 结果为10+1=11
*/
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int count = in.nextInt();
            int[] array = new int[count];
            for (int i = 0; i < count; i++)
                array[i] = in.nextInt();
            Arrays.sort(array);
            int sum = 0;
            for (int i = 0; i < count; i++) {
                if (sum + 1 < array[i]) break;
                sum += array[i];
            }
            System.out.println(sum + 1);
        }
    }
}

编辑于 2017-12-24 09:27:31 回复(0)
从小到大排序,如果前面i个数的和比第i+1个数小2或者更多,就意味着拼死也无法表示(第i+1个数)-1,如果可以表示,则继续往下求和、比较;这里有个特殊情况,就是1,如果输入的最小的比1大,那对方直接说1,就没法表示了。。。
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);
    }
}

发表于 2017-08-17 17:21:17 回复(0)
//////思路: 穷举出所有的组合,每个组合算出数值,放在一个set里。然后使用set的contains方法,从1到set大小查找是否包含该数,没有就返回没找到数,执行结束都没找到,就返回比set大小加1的数。

//////这么一看,时间复杂度应该是n*n。

///// 果然手贱去试着输入了100个数,已经过去五分钟了,现在还在跑呢,所以时间复杂度应该是比我上面说的大的,不知道有没有知道怎么算时间复杂度的?帮忙看一下,谢谢!
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {	
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] arr = new int[n];
		for(int i = 0; i < n; i++){
			arr[i] = sc.nextInt();
		}
		System.out.println(Main(arr,n));
		sc.close();
	}
	
	public static void CombineIncrease(int[] arr, int start, int[] result, int count, int num, Set<Integer> set){
		int i = 0;
		for(i = start; i < arr.length + 1 - count; i++){
			result[count - 1] = i;
			if(count - 1 == 0){
				int j = 0;
				int sum = 0;
				for(j = num - 1; j >= 0; j--){
					sum += arr[result[j]];
				}
				set.add(sum);
			}else{
				CombineIncrease(arr, i + 1, result, count - 1, num, set);
			} 
		}
	}
	private static int Main(int[] arr, int n) {
		Set<Integer> set = new HashSet<Integer>();
		for(int i = 1; i <= n; i++){
			int[] result = new int[i];
			CombineIncrease(arr, 0, result, i, i, set);
		}
		for(int i = 1; i <= set.size(); i++){
			if(!set.contains(i)){
				return i;
			}
		}
		return set.size()+1;
	}
	
}

编辑于 2016-08-13 10:29:38 回复(3)