zoukankan      html  css  js  c++  java
  • 砝码设计-数论

    题目描述 Description

      设有一个没有刻度的天平,可以用来称量

      任务一:设计n个砝码的重量,用它们能称出尽可能多的连续整数重量。例如n=2时,设计两个砝码的重量分别为1和3,可称重为1、2、3、4的连续重量。

      任务二:给出一个重量x(一定能在上面的最优方案下的n个砝码称出),试给出称出x的方案。如在上例中,要称出x=2的方案,方法为2+1:3;称出x=4的方案,方法为:4:1+3,称出x=1的方案为1:1.注意物体放在左边。

     输入输出格式 Input/output
    输入格式:
    键盘输入一行,包括两个数n和x,中间用一个空格隔开。
    输出格式:
    屏幕输出两行,一行为n个砝码的重量(从小到大,每个数之间用一个逗号隔开),第二行为称出x的方案。
     输入输出样例 Sample input/output
    样例测试点#1

    输入样例:

    2 2
    输出样例:

    1,3

    2+1:3

    样例测试点#2

    输入样例:

    2 4
    输出样例:

    1,3

    4:1+3

    思路:
    ①从这题的任务一中不难推导:当n=1时,砝码最优解为1;当n=2时,砝码最优解为1、3;当n=3时,砝码最优解为1、3、9,通过三个例子,我们大概可以得到这样一个结论:砝码的最优解与n有很紧密的相关性,砝码重量为3的0到n-1次方,接下来就用实践检验这个结论。

    ②由于我们的砝码只有n个,并且重量为3的0到n-1次方,所以x必然要用这些砝码表示,不与其他数字有关,并且只能用这些砝码的和或差表示,例如7=1+9-3;2=3-1。当初我最初的想法是用DFS,搜索完每一个砝码,判断是用减号还是加号,最后记录最优解,但由于这题数据范围不确定,n太大了肯定会超时,况且这和数论关系不大,所以必须要想一个简单点的方法。

    ③通过观察可以发现,当x除以3时,如果余数是1,意味着要在砝码盘放上1这个砝码;当x除以3时,如果余数是2,意味着要在物盘放上1这个砝码;如果除以3余数为0,就不用放1这个砝码。同理,把x除以3后四舍五入后再除以3,根据余数判断3这个砝码的位置;再把x除以3后四舍五入再除以3后更加余数判断9这个砝码的位置,以此类推…

    代码如下:

     1 #include <stdio.h>
     2 int main()
     3 {
     4     int A[10],B[10];
     5     int n,x;//n个砝码,要称重量x 
     6     int i,j;//循环兄弟 
     7     int s;//备份用变量 
     8     bool first;
     9     scanf("%d%d",&n,&x);
    10     printf("%d",A[0]=1);//无论n为何值,第一个砝码必定为1
    11     /*===================================================*///解决任务一 
    12     for(i=1;i<n;i++)
    13     {
    14         printf(",%d",A[i]=A[i-1]*3);
    15         printf("
    ");
    16     }
    17     /*===================================================*/
    18     s=x;
    19     for(i=0;i<n;i++)
    20     {
    21         if((s+A[i])%A[i+1]==0)
    22         {
    23             B[i]=1;
    24             s=s+A[i];
    25             continue;
    26         }
    27         if((s-A[i])%A[i+1]==0)
    28         {
    29             B[i]=-1;
    30             s=s-A[i];
    31             continue;
    32         }
    33         A[i]=0;
    34     }
    35     printf("%d",x);
    36     for(i=0;i<n;i++)
    37     {
    38         if(B[i]>0) 
    39         {
    40             printf("+%d",A[i]);
    41         }
    42     }
    43     printf(":");
    44     first=true;
    45     for(i=0;i<n;i++)
    46     {
    47         if(B[i]<0)
    48         {
    49             if(!first)
    50             {
    51                 printf("+");
    52             }
    53             printf("%d",A[i]);
    54             first=false;
    55         } 
    56     }
    57     printf("
    ");
    58     return 0;
    59 }
  • 相关阅读:
    取代iframe,实现页面中引入别的页面
    axios请求
    接口跨域
    es7,es8
    promise
    移动端开发调试工具神器--Weinre使用方法
    资本论第一卷笔记
    2018春季实习生校招面经(一)阿里篇
    linux小实验-考勤模拟程序
    在基于debian的deepin或者Ubuntu上双等号“==”和双中括号“[[]]”不能使用的真相
  • 原文地址:https://www.cnblogs.com/geek-007/p/6288758.html
Copyright © 2011-2022 走看看