题目描述
小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
输入:
两个正整数,表示每种包装中糖的颗数(都不多于1000)
输出:
一个正整数,表示最大不能买到的糖数
样例输入:
4 7
样例输出:
17
题目分析:
此题说通俗一点,就是求由这两个数凑不到的最大数。y = ax + by
解法一:
定义一个长度为15 的整型数组 array,如下所示:
index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
number: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
假设输入的是 3 和 5
赋初值: array[3] = 1; array[5] = 1;
然后我们可以遍历这个数组的,如果被遍历的数组的值是1的话,那么我们把array[i+a]和array[i+b]都赋值为1,赋值为1的意思就是这个数可以被a和b给组合起来的。
但是为了找到最后的大数,我们还要定义两个数计数器 index,count; index是用来表示数组的下标的,而count是用来表示相邻的数组的值为1的个数,如果有连续5个1出现,那么后面的值都可以由3和5凑出来。此时,index表示的下标就是结果。
JAVA 代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
int[] arr = new int[10000];
arr[a] = 1;
arr[b] = 1;
int index = 0;
int count = 0;
int max = a>b?a:b;
for (int i = 1; i < arr.length; i++) {
//
if (0==arr[i]){
index = i;
count = 0;
}else {
arr[i+a] = 1;
arr[i+b] = 1;
count ++;
}
if (count == max){
break;
}
}
System.out.println(index);
}
}
解法二:
首先我们要了解,当num能被a和b组合出来时,只有三种情况:
(1)num%a 等于 0
(2) num%b 等于 0
(3) num = na + mb , (n,m = 1,2…n)
只要弄清这三种原因就好办了,我们可以写一个函数check来判断num是否可以被组合,然后用循环来倒序查找,因为我们知道不能被组合的最大数不可能超过 a ∗ b a*b a∗b, 所以我们可以从 a ∗ b − 1 a*b-1 a∗b−1开始来递减查找,第一次查出来的就是最大的无法组合数。
import java.util.Scanner;
public class Main {
public static boolean Check(int n, int a, int b){
// 情况一:当 n 是 a 或 b 的倍数
if (0==n%a || 0==n%b){
return true;
}
// 情况二:当 n 不能被 a 或 b 整除时
while (n>=a){
if (0 == n%a)
return true;
n = n-b; //这一步必须在判断之后,不然核能会出现n<0的情况
}
return false;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
// 倒序查找,第一次查出来的就是最大的无法组合的数。
for (int i = a*b-1; i > 0; i--) {
if (!Check(i, a, b)) {
System.out.println(i);
break;
}
}
}
}
解法三:
经过上述分析,终于给出了答案。但是这个问题在数学家眼中,就是一个数学公式就可以简单搞定: y = a * b - a - b。这数学公式并不是很容易想到,解法二是最容易想到的。