/*题目描述:
小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
输入:
两个正整数,表示每种包装中糖的颗数(都不多于1000)
输出:
一个正整数,表示最大不能买到的糖数
样例输入
4 7
样例输出
17*/
思路:
很戏剧性的一道题目,刚开始我还在想着啊,a与b不互质则没有解,有一个为1没有解 ,以及各种假设,突然就发现了其中的规律。让暴力大法没有机会施展了。
其实这个啊,a * b - a - b;就是结果
为什么呢?噢,其实只是个巧合啊,我猜的,至少没想到,刚好就可以通过蓝桥杯练习系统了。
#include<iostream>
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
cout << a * b - a - b << endl;
}
当然,技巧是技巧,还是需要好好来做这道题的。
这种题,需要慢慢来推,步骤如下:
用4和7这对参考数据来腿:
这里的i从a开始遍历,所以a = 4,然后,能组成的最小的数就是4,5不可以,6不可以,再然后就是7,8 = 4 + 4,9不可以…
这个时候,中间的一列数代表的是,在上一个数的基础上,我需要减几个才能跟上一个数的最大值一样。例如11,12,两者的最大能取到的数都是10,所以,11-1是最大值,12-2是最大值。
x表示能买的次数连续累加之和,只要可以比小包的个数大,
以后的数都可以拆分成能够买的数的组合,也就是说x取到4是临界值了。
看似无章理的数呢,其实在这个累计的过程中,如果可以让x取到4就可以保证后面的数都是以17为最大值了,在18,19,20,21这四个数,能取到的最大的不可能数字就是17了,在超过了4这个限制之后,后面的每个数字都可以成功得出来。
下面就是代码过程啦
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
#define N 1000 * 100
int recur(int s[], int a)
{
int n = 0;
for(int i = 0; i < sizeof(s) * 4; i++)
{
if(s[i] == 1)
{
n++;
if(n >= a) return i - a;
}
else
n = 0;
}
return -1;
}
int f(int a, int b)//从1开始向上找
{
int s[N];
for(int i = 0; i <= N / a; i++)
{
for(int j = 0; j <= (N - i * a) / b; j++)
{
if(i * a + b * j < N)
s[i * a + b * j] = 1;
}
}
return recur(s, a);
}
int main()
{
int a,b;
cin >> a >> b;
cout << f(a,b);
return 0;
}