买不到的数目

/*题目描述:
小明开了一家糖果店。他别出心裁:把水果糖包成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;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Αиcíеиτеǎг

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值