时间限制: 1Sec 内存限制: 128MB 提交: 2378 解决: 789
题目描述
小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有N种蒸笼,其中第i种蒸笼恰好能放Ai个包子。每种蒸笼都有非常多笼,可以认为是无限笼。
每当有顾客想买X个包子,卖包子的大叔就会迅速选出若干笼包子来,使得这若干笼中恰好一共有X个包子。比如一共有3种蒸笼,分别能放3、4和5个包子。当顾客想买11个包子时,大叔就会选2笼3个的再加1笼5个的(也可能选出1笼3个的再加2笼4个的)。
当然有时包子大叔无论如何也凑不出顾客想买的数量。比如一共有3种蒸笼,分别能放4、5和6个包子。而顾客想买7个包子时,大叔就凑不出来了。
小明想知道一共有多少种数目是包子大叔凑不出来的。
输入
第一行包含一个整数N。(1 <= N <= 100) 以下N行每行包含一个整数Ai。(1 <= Ai <= 100)
输出
一个整数代表答案。如果凑不出的数目有无限多个,输出INF。
样例输入复制
2 4 5
样例输出复制
6
阅读完此题 很多同学都特别的苦恼,这该如何下手呢,很多同学都会从暴力下手,然而这道题用暴力是固然不行的。其实2017年的这道题与2013年蓝桥杯的某一道特别类似,不知道同学们发现了没有了。17年这道题目叫做凑不出的包子,13年那道题叫做凑不出的数。其思想核心是不变的,接下来我来谈谈如何解决这类题型,希望有获得帮助的同学为我点点赞,你的点赞是我不断更新的动力 ~.~
首先我们对输入样例2 4 5进行分析,2是代表有两个整数,那么4 5 不能凑出哪些数呢,我们通过简单的计算如下
然后我们会发现如下规律:
我们会发现,4 5这两个数除了1 2 3 6 7 11这六个数,其他都能凑出来,我们再来看看4 6 这两个数,它们不能凑出哪些数呢?这想都不用想,首先都一点,它们连所有的奇数都凑不来,为什么这么说呢,因为这两个数是偶数 4x+6y 的结果也必然是偶数,所以根本无法凑出奇数,所以凑不出的数有无限个。
综上这一点我们会发现,如果两个数的公约数都不为1,那么必然凑不出的数有无限个的 !这一点是毫无疑问的,所以我们可以先对N个数进行gcd()求公约数,这种方法又叫辗转相除法求公约数,如下
然后我们再来来了解一点,那就是,如果4是能被凑出来的,那么4+4等于8, 8也必然是能凑出来的,因为8能凑出来,那么8+4等于12,12也是可以凑出来的,以此类推16,20,24...也都是可以凑出来的,知道了这些那么,接下来就附上代码啦,如下:
package test;
import java.util.*;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
int N=sc.nextInt();
int[] arr=new int[N];
int zhi=0;
boolean[] f=new boolean[10000]; //定义数组f,此数组为布尔型数组,用了表示当前的索引能否凑出来,凑出来就为true,否则为false
f[0]=true; //并定义首个索引为true
for(int i=0;i<N;i++) {
arr[i]=sc.nextInt();
if(i==0) {
zhi=arr[0];
}
else { //求arr数组中所有元素的公约数
zhi=gcd(arr[i],zhi);
}
for(int j=0;j<10000-arr[i];j++) {
if(f[j]) { //以此递归,例如当f[0]为真,那么f[4+0]=true,即4能凑出来,以此类推,当f[4]=true,那么f[4+4]=true,所以8凑出来,以此类推12,16,20均可以凑出来
f[arr[i]+j]=true;
}
}
}
if(zhi!=1) { //如果arr数组中所有元素的公约数不等于1,那么必然凑不出偶数,则输出“INF”
System.out.println("INF");
return;
}
int count=0;
for(int i=0;i<10000;i++) {
if(f[i]==false) count++;
}
System.out.println(count);
}
public static int gcd(int a,int b) { //利用辗转相除法求公约数
if(b==0) {
return a;
}
else {
return gcd(b,a%b);
}
}
}
如果小伙伴有更好的奇思妙想,绝世武功,欢迎在留言区留下你的足迹哦 ~.~