标签:
题意
T组测试数据,每组数据给你n(0<n<=1000)个无符号整型范围内的数,把这些数字任意排列后连接成一个大数,求能排出的所有数当中最大的与最小的两个数的差值。
例如{1, 2}, 最大为21,最小为12,差值为9。
样例输入
1
3
1 2 3
样例输出
198
思路
乍一看是个大数问题,然而后来发现排序才是这道题的重点。
一开始想的是按数字的大小排序,但显然不对。例如{9, 10},按数字排序的话9 < 10,则最小值为910,但是显然109更小。
后来想到按字典序排,并且深信不疑的WA了两次(0﹏0)
例如{9, 90},按字典序排的话是9 < 90,则最小值为990,但显然909更小。
最后才想到要把两个字符串拼接以后再按字典序排。例如{567, 5674}就比较5675674和5674567哪个更小,显然后者小,所以排序后的结果应为{5674, 567}。
用C++的string的话可以很优美的实现这个比较函数。
bool cmp(const string a, const string b){ return (a+b) < (b+a); }
然而不知道是C++的读入太慢还是string慢,居然超时了(⊙_⊙)
然后加上一句取消cin与stdin同步以后就险过了~~~2644ms(时限3000ms)
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <string> 5 using namespace std; 6 const int N = 1e3+10; 7 string str[N], sMax, sMin; 8 bool cmp(const string a, const string b){ 9 return (a+b) < (b+a); 10 } 11 void Subtract(void) 12 { 13 int len = sMax.length(); 14 for(int i=len-1; i; --i) 15 { 16 if(sMax[i] >= sMin[i]) 17 sMax[i] -= sMin[i] - ‘0‘; 18 else 19 sMax[i] -= sMin[i] - 10 - ‘0‘, --sMax[i-1]; 20 } 21 sMax[0] -= sMin[0] - ‘0‘; 22 int i; 23 for(i=0; i<len && sMax[i] == ‘0‘; ++i); 24 if(i == len) 25 cout << 0 << endl; 26 else 27 { 28 for(; i<len; ++i) 29 cout << sMax[i]; 30 cout << endl; 31 } 32 } 33 int main(void) 34 { 35 std::ios::sync_with_stdio(false); 36 int kase, n; 37 cin >> kase; 38 while(kase--) 39 { 40 cin >> n; 41 for(int i=0; i<n; ++i) 42 cin >> str[i]; 43 sort(str, str+n, cmp); 44 sMax = sMin = ""; 45 for(int i=0; i<n; ++i) 46 sMin += str[i]; 47 for(int i=n-1; i>=0; --i) 48 sMax += str[i]; 49 Subtract(); 50 } 51 }
标签:
原文地址:http://www.cnblogs.com/gwtan/p/5869295.html