蓝桥杯训练:爆搜——天平称重

问题描述:
用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。
如果只有5个砝码,重量分别是1,3,9,27,81。则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中)。
本题目要求编程实现:对用户给定的重量,给出砝码组合方案。
例如:
用户输入:
5
程序输出:
9-3-1
用户输入:
19
程序输出:
27-9+1
要求程序输出的组合总是大数在前小数在后。
可以假设用户的输入的数字符合范围1~121。
【解题思路提示】
我们把已知的砝码序列记为:x1, x2, x3, x4, x5, x6 (这里多加一个标准砝码,为解题叙述方便)
对于任意给定的重量x,如果刚好等于xi 则问题解决。
否则一定会位于两个标准砝码重量的中间,不妨设为:xi < x < xj
令 a = x – xi,  b = xj – x
则,x 要么可以表示为: xi + a, 要么可以表示为: xj – b
这样问题就归结为怎样表示出 a 或 b
另一思路:对于每个xi,可以乘以一个系数ki,再求和。
ki的数值无外乎:-1 0 1
这样,因为标准砝码的数量的很少的,我们就可以多层循环暴力组合ki来求解。
还有更“土气”但有效的思路:既然输入范围只有120左右,如果对每一种情况都做人工求解,只要列一个大表,等查询的时候,直接输出答案就好了啊!但…这似乎是个耗时的工程…
作者:何知令

完成时间:2017年5月13日

这里选用的是第二种方法

代码如下:

/*
问题描述:
用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。
如果只有5个砝码,重量分别是1,3,9,27,81。则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中)。
本题目要求编程实现:对用户给定的重量,给出砝码组合方案。
例如:
用户输入:
5
程序输出:
9-3-1
用户输入:
19
程序输出:
27-9+1
要求程序输出的组合总是大数在前小数在后。
可以假设用户的输入的数字符合范围1~121。
【解题思路提示】
我们把已知的砝码序列记为:x1, x2, x3, x4, x5, x6 (这里多加一个标准砝码,为解题叙述方便)
对于任意给定的重量x,如果刚好等于xi 则问题解决。
否则一定会位于两个标准砝码重量的中间,不妨设为:xi < x < xj
令 a = x – xi,  b = xj – x
则,x 要么可以表示为: xi + a, 要么可以表示为: xj – b
这样问题就归结为怎样表示出 a 或 b
另一思路:对于每个xi,可以乘以一个系数ki,再求和。
ki的数值无外乎:-1 0 1
这样,因为标准砝码的数量的很少的,我们就可以多层循环暴力组合ki来求解。
还有更“土气”但有效的思路:既然输入范围只有120左右,如果对每一种情况都做人工求解,只要列一个大表,等查询的时候,直接输出答案就好了啊!但…这似乎是个耗时的工程…
作者:何知令
完成时间:2017年5月13日
*/
#include <stdio.h>
#include <stdlib.h>
void sort(int w[])
{
    int have=1;
    int i,t;
    while(have!=0)
    {
        have=0;
        for(i=0; i<4; i++)
        {
            if(w[i]<w[i+1])
            {
                t=w[i];
                w[i]=w[i+1];
                w[i+1]=t;
                have++;
            }
        }
    }
}
int main()
{
    int state[5];
    int n,o;
    int first;
    int w[5]= {1,3,9,27,81};
    while(~scanf("%d",&n))
    {
        first=0;
        for(state[0]=-1; state[0]<2; state[0]++)
            for(state[1]=-1; state[1]<2; state[1]++)
                for(state[2]=-1; state[2]<2; state[2]++)
                    for(state[3]=-1; state[3]<2; state[3]++)
                        for(state[4]=-1; state[4]<2; state[4]++)
                        {
                            if(w[0]*state[0]+w[1]*state[1]+w[2]*state[2]+w[3]*state[3]+w[4]*state[4]==n)
                            {
                                sort(w);
                                for(o=0; o<5; o++)
                                {
                                    if(state[o]==-1)
                                        printf("-%d",w[o]);
                                    else if(state[o]==1)
                                    {
                                        if(first==1)
                                            printf("+");
                                        printf("%d",w[o]);
                                    }
                                    first=1;
                                }
                                printf("\n");
                            }
                        }
    }
    return 0;
}
程序云结果展示:



知识点总结:爆搜,结构控制,函数使用

学习心得:没提示我不会....得想办法提升自己的解题思路

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值