2006 ACM亚洲区域赛西安赛区题目B--Bigger is Better

1 篇文章 0 订阅

题目:

基本思路是:
        首先判断能否组成题目要求的数字,显然当n<2m时和n>7m时都是不可能的。
        如果想让这个数字尽量的大,那么就要让他的高位尽量的大,在满足低位能组成完整的数字的情况下。
        我们可以先给所有的位赋值为“9”,这当然是在某个特定的n(n=6m)的情况下的最大的数了,但是,并不一定n就满足这个条件,然后我们就要看n和6m相差多少了。
        如果6m>n,就是有剩余,我们就要考虑使用消耗火柴更多一些的数字,在这里只有8了。为了保证数字的最大,我们在讲数字改小的时候要从最后面开始。这样的话,如果剩余tempn根火柴,我们只要把最后的tempn个数字改成8就行了。
        如果6m<n,即火柴不够组成那么多的9,那么我们就要考虑使用消耗火柴少的数字了,由于低位数字的调整对数字大小的影响要小于高位的数字的调整,因此,我们尽量在最低位的时候就把这个“赤字”给补回来,即用最低位还最多的债,只能是先变成1了。然后看是否依然亏空。是,则继续用次低位还债,否,如果刚好还清,则完成,出现了多余,就要重新设定最后一次改变的数字,使用我们程序开头设定的一个数组来设定该数字,使其刚好把火柴用完。
        上面关于6m<n的分析看起来繁琐,其实在实现的时候很简单的,1和9使用火柴的数量相差4根,如果差tempn根火柴,那么就把最后tempn/4个数字变成1,然后将后面第tempn/4+1个数字变成数组中的matches[6-tempn%4](因为数字9占用6根火柴,现在号要再还tempn%4根才能还清亏空,所以这里的数字要变成一个由6-tempn%4根火柴组成的最大的数字了)。
        程序实现如下(没有写文件读写部分,只是实现了算法,因此输入是从键盘输入,输出到显示器): 

# include <conio.h>
# include <math.h>
main()
{
        char matches[8]={'0','0','1','7','4','5','9','8'};
        int n,m,tempn,tempm,i;
        char *p;
        printf("/nPlease enter the m,n:");
        scanf("%d,%d",&m,&n);
        if ((n<2*m)||(n>7*m))
        {
                printf("/n-1");
                exit(1);
        }
        p=(char*)malloc(m+1);
        p[m]='/0';
        for(i=0;i<m;i++) p[i]='9';
        tempn=m*6-n;
        if (tempn==0)
        {       printf("/n%s",p);
                exit(1);
         }
        if (tempn<0)
        {
                tempn=abs(tempn);
                for(i=0;i<tempn;i++) p[m-i-1]='8';
         }
         else
         {
                tempm=tempn/4;
                tempn-=tempm*4;
                for(i=0;i<tempm;i++)
                {
                        p[m-i-1]='1';
                }
                p[m-tempm-1]=matches[6-tempn];
          }
          printf("/n%s",p);
 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值