题目描述
设有 n 个正整数 a1…an,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数。
输入格式
第一行有一个整数,表示数字个数 n。
第二行有 n 个整数,表示给出的 n 个整数 ai。
输出格式
一个正整数,表示最大的整数
输入输出样例
输入 #1
3
13 312 343
输出 #1
34331213
输入 #2
4
7 13 4 246
输出 #2
7424613
说明/提示
对于全部的测试点,保证 1≤n≤20,1≤ai≤10^9。
题解
哇,感觉这是我最近这段时间一来收获最多的一道单题。
因为只是接住了基础知识,具体实现思路都是自己写的。就很得劲。
这一看显然就是sort对string数组的排序。
最初代码
#include<bits/stdc++.h>
using namespace std;
string s[30];
bool cmp(string a,string b)
{
return a.compare(b);
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s[i];
}
sort(s+1,s+n+1,cmp);
for(int i=1;i<=n;i++) cout<<s[i];
return 0;
}
当时脑袋没有完全转过完来,谁知这反而引出了问题(其实明明可以先不写cmp,就从小到大排,然后倒着输出就好)
我这样写,样例1ok,但2却发生了错误。
理论上结果为 7424613,但实际...
???
思索后觉得是cmp比较函数写的有问题。
遂复习了下原理。
那么我的比较a.compare(b)的返回值又是怎么样的呢?
当a>b 返回正值
a==b 返回0
a<b 返回负值
等等,是当两个字符串a==b时,才返回0,二者不等时返回正数/负数。
我擦,找到问题了!!!
我把比较结果作为bool函数的返回值,我希望a>b时返回true,a<b时返回false。
但是实际上并不是这样,现在是只有当a与b相等时,才返回false,a与b不等就会返回true。
原来如此。
于是我修改了cmp函数。
bool cmp(string a,string b)
{
int result = a.compare(b); //记录比较的返回值
if(result>=0) return true;
else return false;
}
这样我得了75分。
还剩最后一个点。
后面的是我的程序输入+输出,前面的记事本是题目要求的输入+输出。
明显地可以看出不同,
我的程序:321 32
正确答案:32 321
想了以下,从追求数的大小来看,确实是这样。
我的问题:
当有两个字符串a,b,二者长度不同,但前面有一部分相同(且相同的部分就是那个短的字符串本身)。
按我的字符串比较,走完前面相同的,接下来比较时,b还有字符,但a已经没有了(看作那一位为'\0'),这样自然时b>a。
但在这里不行。
其实输入样例的后面还有一对,即135 和 13。
这部分我却没有排错。
我看出,除去前面的部分,长的字符串b的接下来的那一位要与短的a的开头那个字符进行比较。
对于321, 32 就是拿1与3比较,1<3,所以二者排序时把32放在了前面,成为32321。
对于135,13 就是拿5与1比较,5>1,所以把135放在了前面,成为13513。
遂重写cmp。
这一次我总算完全搞懂了cmp的原理和写法(因为我写了好多呀)
bool cmp(string a,string b)
{
int size_a=a.size(),size_b=b.size();
for(int i=0;i<min(size_a,size_b);i++) //前面的部分
{
if(a[i]>b[i]) return 1;
else if(a[i]==b[i]) continue;
else return 0;
}
if(size_a==size_b) return 1;
//前面都一样,后面长度不同
if(size_a<size_b) //a走完了,b还有
{
if(b[size_a]>a[0]) return 0;
else if(b[size_a]<a[0]) return 1;
}
}
ac代码
#include<bits/stdc++.h>
using namespace std;
string s[30];
bool cmp(string a,string b)
{
int size_a=a.size(),size_b=b.size();
for(int i=0;i<min(size_a,size_b);i++)
{
if(a[i]>b[i]) return 1;
else if(a[i]==b[i]) continue;
else return 0;
}
if(size_a==size_b) return 1;
//前面都一样,后面长度不同
if(size_a<size_b) //a走完了,b还有
{
if(b[size_a]>a[0]) return 0;
else if(b[size_a]<a[0]) return 1;
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s[i];
}
sort(s+1,s+n+1,cmp);
for(int i=1;i<=n;i++) cout<<s[i];
return 0;
}
补充:
我再后来翻看大佬的思路时,惊奇的发现原来有很简洁的cmp。
bool cmp(string a,string b)
{
return a+b>b+a;
}
啊这...我服啦(写了那么多代码的我留下了眼泪)
而且,string可以直接比较啊喂。
当涉及string 的直接比较时,用比较运算符就行啦,也就是>、<、==、>=、<=、!= 等。
当然这也不是说a.compare(b)没用,它是支持多参数的,当我对比较有严格要求时,就要用它了。