买不到的数目 蓝桥杯 c++

小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。

小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。

你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。

本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。

输入:
两个正整数,表示每种包装中糖的颗数(都不多于1000)

要求输出:
一个正整数,表示最大不能买到的糖数

不需要考虑无解的情况

例如:
用户输入:
4 7
程序应该输出:
17

再例如:
用户输入:
3 5
程序应该输出:
7

思路一:
数论
利用了pei’shu
如果a,b均是正整数且互质,那么由 ax+by,x≥0,y≥0不能凑出的最大数是(a−1)(b−1)−1
引理:给定a,b,若gcd(a,b)>1,则一定不能凑出最大数
利用了裴蜀定理。

#include
using namespace std;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	int n, m;
	cin >> n >> m;
	cout << (n-1) * (m-1) - 1 << endl;
	return 0;
}

思路二:
dp
用bool数组dp[i]表示能否组合成i,将dp[0],dp[n]和dp[m]都置为1
for循环遍历,每遍历到一个数,都要看看dp[i - n]或dp[i -m]是否为1,如果是,则置true,否则就更新ans
从n和m中较大的数开始遍历,遍历到nm即可,因为我们已经将dp[0],dp[n]和dp[m]都置为1,且易得比nm大的数必定可以被n,m组合
ans就是指最大不能买的数目,循环结束,便可直接输出ans
具体操作见代码

#include
using namespace std;
const int N = 1e6 + 5;
bool dp[N]; 

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	int n, m, ans;
	cin >> n >> m;
	dp[0] = 1;
	dp[n] = dp[m] = 1;
	int maxn = max(n, m);
	for(int i = maxn; i < n * m; i ++ ){
		if(dp[i-n] || dp[i-m])
			dp[i] = 1;
		else
			ans = i;
	}
	cout << ans << endl;
	return 0;
}

转载于作者文章

你可能感兴趣的:(蓝桥杯历届题目分析)