目录
题目描述:
给定数字 0-9 各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意 0 不能做首位)。例如:给定两个 0,两个 1,三个 5,一个 8,我们得到的最小的数就是 10015558。
现给定数字,请编写程序输出能够组成的最小的数。
输入格式:
输入在一行中给出 10 个非负整数,顺序表示我们拥有数字 0、数字 1、……数字 9 的个数。整数间用一个空格分隔。10 个数字的总个数不超过 50,且至少拥有 1 个非 0 的数字。
输出格式:
在一行中输出能够组成的最小的数。
输入样例:
2 2 0 0 0 3 0 0 1 0
输出样例:
10015558
题目讲解:
给出若干个数想组成最小数,组合数数位越高,放的数字就应该越小。所以组合数至少从次高位开始到最低位为止,每个数位上的数字是逐渐递增的。
为什么说是“至少”呢?因为一个组合数第一位不能是0,如果给出的数字中至少给了一个0,那么整个组合数至少前两位的数字就不可能是递增的了。
这个时候,就必须选择一个尽可能小的数字来充当组合数的最高位。
框架构建:
【1】如果1~9这九个数字都没给
输出0;直接结束程序;
否则:
【2】 数字0给了几个?
【2.1】没给0
按照顺序输出;
【2.2给了至少一个0】
找一个尽量小的数字放在最高位,其他数字按照顺序输出;
代码部分:
#include <iostream>
using namespace std;
struct com
{
int number;
int num;
};
int main()
{
com x[10];
int temp;//输入每个数字给的个数
int cnt0 = 0;//查0,如果1~9这九个数字都没给,那么将输出0之后结束程序.
for (int i = 0; i < 10; i++)
{
cin >> temp;
x[i].number = i;
x[i].num = temp;//赋值
if (i>0&&temp == 0)
cnt0++;//统计
}
//如果1~9这几个数字都为0,那么结果应该输出0.
if (cnt0 == 9)
{
cout << 0;
return 0;
}
//判断是否需要从后面向前补位.
//如果含有数字0,那么就需要从后面补位.
//如果没给数字0,直接按顺序输出,就是最小的数.
//下面是没给数字0的情况
if(x[0].num==0)
for (int i = 0; i < 10; i++)
{
if (x[i].num != 0)
{
for (int j = 0; j < x[i].num; j++)
cout << x[i].number;
}
}
//下面是给了数字0的情况.
else if(x[0].num!=0)
{
//cout << "code has run to here!" << endl;
int not0 = -1;//标记.看看至少需要哪个数字来补位
for (int i = 1; i < 10; i++)
if (x[i].num != 0)
{
not0 = i;
x[i].num -= 1;//这个非零数字原来有x[i].num个,
//现在其中一个放到了组合数最前面,所以现在有x[i].num-1个.
//cout << x[i].number << endl;
break;
}
cout << x[not0].number;//先输出补位的数字
for (int i = 0; i < 10; i++)
{
if (x[i].num!=0)
for (int j = 0; j < x[i].num; j++)
cout << x[i].number;//其他数字按照其个数输出.
}
}
return 0;
}
一个bug:
这道题题目描述和检测机制是不严谨的。题目没有考虑“如果1~9这九个数字,如果他们的个数都输入为0,那么应该输出0” 这种情况。
在评测机上运行的时候,对这个bug的判断与否竟然没有影响答案正确与否,乐