问题:
有N个0到9的数字,互不重复。用这些数字组成2个整数,每个数字只能用一次,且必须用尽所有数字,且0不能在第一位(除非组成的整数是0)。求组成整数的差的最小值。
思路:
可以将所有情况分为两类:
(1)N是偶数:可以将这N个数字平分,使每个整数含N/2个数字。要使差最小,只需使两个整数最高有效位的差最小,然后使用贪心算法使次高有效位及以后的位数的差 最大。这里使两个整数最高有效位的差最小的做法可能有多种,因此要枚举每种做法,取出最后结果值最小的那一个。
(2)N是奇数:将N个数字中除0外的最小数字分配给其中一个整数,作为最高有效位。然后将剩余的数字平分,从高位到低位贪心取差最大的两个数字。
代码:
1 #include<iostream> 2 #include<string> 3 #include<vector> 4 using namespace std; 5 6 int main(){ 7 int N; 8 string temp; 9 cin >> N; 10 getline(cin, temp); 11 while(N--){ 12 vector<int> digit; 13 getline(cin, temp); 14 for(int i = 0; i < temp.size(); i += 2){ 15 digit.push_back(temp[i] - '0'); 16 } 17 if(digit.size() == 2){ 18 cout << digit[1] - digit[0] << endl; 19 }else if(digit.size() % 2 == 0){ 20 int min_inter = 10000; 21 for(int i = 0; i + 1 < digit.size(); i++){ 22 if(digit[i] != 0 && digit[i + 1] - digit[i] < min_inter) 23 min_inter = digit[i + 1] - digit[i]; 24 } 25 int MIN = 10000; 26 for(int i = 0; i + 1 < digit.size(); i++){ 27 if(digit[i] != 0 && digit[i + 1] - digit[i] == min_inter){ 28 vector<int> left; 29 vector<int> right; 30 left.push_back(digit[i]); 31 right.push_back(digit[i+1]); 32 for(int j = 0, k = digit.size() - 1; j < k; j++, k--){ 33 if(j == i || j == i + 1){ 34 k++; 35 continue; 36 } 37 if(k == i || k == i + 1){ 38 j--; 39 continue; 40 } 41 left.push_back(digit[k]); 42 right.push_back(digit[j]); 43 } 44 int a = 0, b = 0; 45 for(int j = 0; j < left.size(); j++){ 46 a = (10 * a + left[j]); 47 } 48 for(int j = 0; j < right.size(); j++){ 49 b = (10 * b + right[j]); 50 } 51 if(MIN > b - a) 52 MIN = b - a; 53 } 54 } 55 cout << MIN << endl; 56 }else{ 57 vector<int> left; 58 vector<int> right; 59 int i; 60 if(digit[0] == 0){ 61 i = 1; 62 right.push_back(digit[1]); 63 }else{ 64 i = 0; 65 right.push_back(digit[0]); 66 } 67 for(int j = 0, k = digit.size() - 1; j < k; j++, k--){ 68 if(j == i){ 69 k++; 70 continue; 71 } 72 if(k == i){ 73 j--; 74 continue; 75 } 76 left.push_back(digit[k]); 77 right.push_back(digit[j]); 78 } 79 int a = 0, b = 0; 80 for(int j = 0; j < left.size(); j++){ 81 a = (10 * a + left[j]); 82 } 83 for(int j = 0; j < right.size(); j++){ 84 b = (10 * b + right[j]); 85 } 86 cout << b - a << endl; 87 } 88 } 89 }