题目:
基本思路是:
首先判断能否组成题目要求的数字,显然当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);
}