包子凑数
小明几乎每天早晨都会在一家包子铺吃早餐。
他发现这家包子铺有 N 种蒸笼,其中第 i 种蒸笼恰好能放 Ai 个包子。
每种蒸笼都有非常多笼,可以认为是无限笼。
每当有顾客想买 X 个包子,卖包子的大叔就会迅速选出若干笼包子来,使得这若干笼中恰好一共有 X 个包子。
比如一共有 3 种蒸笼,分别能放 3、4 和 5 个包子。
当顾客想买 11 个包子时,大叔就会选 2 笼 3 个的再加 1 笼 5 个的(也可能选出 1 笼 3 个的再加 2 笼 4 个的)。
当然有时包子大叔无论如何也凑不出顾客想买的数量。
比如一共有 3 种蒸笼,分别能放 4、5 和 6 个包子。
而顾客想买 7 个包子时,大叔就凑不出来了。
小明想知道一共有多少种数目是包子大叔凑不出来的。
输入格式
第一行包含一个整数 N。
接下来 N 行,每行包含一个整数 Ai。
输出格式
输出一个整数代表答案。
如果凑不出的数目有无限多个,输出INF。
数据范围
1≤N≤100,
1≤Ai≤100
输入样例1:
2
4
5
输出样例1:
6
输入样例2:
2
4
6
输出样例2:
INF
样例解释
对于样例1,凑不出的数目包括:1, 2, 3, 6, 7, 11。
对于样例2,所有奇数都凑不出来,所以有无限多个。
思路: 可以用完全背包来做,但是这里介绍另一种思路。假设我们输入的n个数,他们的最大公约数都不是1 。即 :他们都是偶数或者都是奇数 。那么 ,肯定有无数多个数是凑不出来的 。直接输出INF即可 。反之 ,我们找到n个数中最小的那个数 ,一旦我们所凑出来的连续数据长度等于这个最小数 ,那么后面的所有数 ,都可以被凑出来了,对不对?想到这里 ,本题就解决了 。
#include <stdio.h>
int n,a[105],dp[1000000],f,MIN=111,ans;
int gcd(int a,int b)
{
return !b?a:gcd(b,a%b);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
dp[a[i]]=1;
if(a[i]<MIN)
MIN=a[i];
}
for(int i=2;i<=n;i++)
{
for(int j=1;j<i;j++)
{
if(gcd(a[j],a[i])==1)
{
f=1;
break;
}
}
}
if(!f)
{
printf("INF");
return 0;
}
int q=1,p=0;
while(p<MIN)
{
if(dp[q]==1)
{
p++;
for(int i=1;i<=n;i++)
{
dp[q+a[i]]=1;
}
}
else
{
p=0;
ans++;
}
q++;
}
printf("%d",ans);
return 0;
}
买不到的数目
【题目】
小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
输入:
两个正整数,表示每种包装中糖的颗数(都不多于1000)
要求输出:
一个正整数,表示最大不能买到的糖数
例如:
用户输入:
4 7
程序应该输出:
17
再例如:
用户输入:
3 5
程序应该输出:
7
资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
思路 : 和上一题完全一样 。我们只需要记录下最后满足条件的序列前最后一个不能被凑出来的即可 。
#include <stdio.h>
int n,aa,bb,f,ans,min,b[1000005],p,q=1;
int MIN(int x,int y)
{
return x<y?x:y;
}
int main()
{
scanf("%d%d",&aa,&bb);
b[aa]=1;
b[bb]=1;
min=MIN(aa,bb);
while(p<min)
{
if(b[q])
{
p++;
b[aa+q]=1;
b[bb+q]=1;
}
else
{
p=0;
ans=q;
}
q++;
}
printf("%d",ans);
return 0;
}