NYOJ 1233 差值(字符串排序+大数减法)

题意
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 }
原文地址:https://www.cnblogs.com/corvey/p/5869295.html