Description
小灰灰同学最近迷上了一个数字游戏,这个数字游戏的规则如下:给你一组数字片段,将这些数连接起来得出一个最小的数。例如:给出32,321,3214,0229,87,我们可以将这些数按不同的顺序连接起来可以得到如32-321-3214-0229-87或0229-32-87-321-3214的数,最小的数0229-32-87-321-321。
Input
数据的第一个行是一个T,代表程序要执行的次数(T小于10)。
然后是T组测试数据,每一组测试数据的第一个是一个正整数N(N小于10000),接下来是N个数字片段,数字片段不会超过9位。数字片段间有空格隔开。
Output
对于每一组测试数据,输出一个最小的数。不要输出前导0。
Sample Input
2
3 045 023 22
5 32 321 3214 0229 87
Sample Output
2304522
22932132143287
HINT
说实话这道题确实对于我来说有点难度,题目意思很明确,就是由这些数字片段来组成一个新的数,要求是最小。很明显如果前面有0的话,越放在高位,数字就越小。这道题,我的第一反应就是排序,但是令我很麻烦的是,用什么来存这些数据了,另外怎样确定优先级了。我后面在草稿上画了很久发现了一个规律,第一数字越小的放在高位肯定比其他大的要小。另外,如果第一位如果相同该怎么办了?这是最重要的地方了。
这句代码的意思就是看两个字符串连接后小的优先级高,如果s1+s2之后的数<s2+s1之后的数,就把s1放在前面。这个很明显是正确的。
例如上面的第二例子,以3开头的数字片段有三个,以321,3214,为了方便表达,我将他们两个依次编号为1,2(这里的+表示连接)
1+2=3213214 2+1=3214321
所以321要放在3214前面。
最后就是该如何存储的问题。由于最近学了比较多stl里面的东西,所以想到了用vector来存。这个vector本身就是一个容器,只要给定数据类型就可以了,并且可以方便的往其中添加数据。
好了,该说的终于说完了,是到上代码的时间了,激动啊
<span style="font-size:18px;">#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include<cstdio>
using namespace std;
vector<string> num[10];
bool cmp(string s1, string s2){
return s1 + s2 < s2 + s1;
}
int main(){
int t;
scanf("%d",&t);
while(t--)
{
for(int i=0;i<10;i++)//必须清空
num[i].clear();
string temp,tempI,result="";
int n,i;
cin >> n;
for(i = 0; i < n; i++){
cin >> temp;
num[temp[0] - '0'].push_back(temp);//将有相同第一个数字放在同一个num中
}
for (i = 0; i < 10; i++){
if (num[i].size() != 0)//对每一个有相同第一个数字的进行排序
sort(num[i].begin(), num[i].end(), cmp);
for (vector<string>::iterator vI = num[i].begin(); vI != num[i].end(); vI++){
result = result + *vI;
}
/*for(vector<string>::iterator iter1=num[i].begin(); iter1!=num[i].end(); ++iter1 ){
for( size_t sty=0;sty!=(*iter1).size(); ++sty){
cout<< (*iter1)[sty] ;
}
cout <<endl ;
}*/
}
int len=result.length();
for (i = 0; i <len ; i++){
if (result[i] != '0')
break;
}
if (i == len)//如果数字为0必须单独处理
printf("0\n");
else
cout << result.substr(i,result.size())<<endl;
}
return 0;
}</span>
哎,每一次比赛就觉得自己跟那些强者差很多啊!!!