soj 1239. Smallest Differencev
2013-01-07 15:32
253 查看
题意:
给定n(2 <= n <= 10)个不重复的十进制数字('0'-'9'),让这n个数字不重复使用地构成两个数,使这两个数的差的绝对值最小。
比如,0 1 2 4 6 7,构成176 和 204 能使差最小为28。
思路:
贪心。分情况讨论。
1)是有奇数个数的话,那么,选择非零的最小的数字作为较大数的最高位,最后一位数字作为较小数的最高位,然后较大数从后往前取次位,较小数从前往后取次位。
如0 1 2 4 5 7 8,较大数的最高位就是1(次高位可以直接判断出来是0),较小数的次高位就是8,然后依次取,得到(10,8),(102,87),(1024,875),就能得到答案。
2)是有2个数的话,那么直接两个数相减就能得到答案。
3)非2个的偶数个数,这是比较麻烦的一种情况,首先必须使最高位的差最小,就可以遍历一遍找到最高位的差的最小值。然后再遍历一遍,对每一对最高位的差为最小值的两个数进行枚举,较小数的最高位为较小的那个数,较大数的最高位为较大的那个数,较大数的次位从前往后取,较小数的次位从后往前取。
如1 3 5 7,最高位的差为2,枚举所有的最高位的差为2 的数对(1,3),(3,5),(5,7)。然后取次位,分别得到(1,3)-> (17,35)= 18,(3,5)-> (37,51)= 14,(5,7)-> (53,71)= 18,比较得到答案为14。
注意:
读入数据的时候可以用stringstream或其他。
代码:
给定n(2 <= n <= 10)个不重复的十进制数字('0'-'9'),让这n个数字不重复使用地构成两个数,使这两个数的差的绝对值最小。
比如,0 1 2 4 6 7,构成176 和 204 能使差最小为28。
思路:
贪心。分情况讨论。
1)是有奇数个数的话,那么,选择非零的最小的数字作为较大数的最高位,最后一位数字作为较小数的最高位,然后较大数从后往前取次位,较小数从前往后取次位。
如0 1 2 4 5 7 8,较大数的最高位就是1(次高位可以直接判断出来是0),较小数的次高位就是8,然后依次取,得到(10,8),(102,87),(1024,875),就能得到答案。
2)是有2个数的话,那么直接两个数相减就能得到答案。
3)非2个的偶数个数,这是比较麻烦的一种情况,首先必须使最高位的差最小,就可以遍历一遍找到最高位的差的最小值。然后再遍历一遍,对每一对最高位的差为最小值的两个数进行枚举,较小数的最高位为较小的那个数,较大数的最高位为较大的那个数,较大数的次位从前往后取,较小数的次位从后往前取。
如1 3 5 7,最高位的差为2,枚举所有的最高位的差为2 的数对(1,3),(3,5),(5,7)。然后取次位,分别得到(1,3)-> (17,35)= 18,(3,5)-> (37,51)= 14,(5,7)-> (53,71)= 18,比较得到答案为14。
注意:
读入数据的时候可以用stringstream或其他。
代码:
#include <iostream> #include <sstream> #include <algorithm> #include <cstring> using namespace std; int t, n, num[10], a, b, ans; string data; int main() { ios::sync_with_stdio(false); cin >> t; getline(cin, data); while (t --) { getline(cin, data); n = 0; stringstream sin(data); while (sin >> num[n++]); n --; sort(num, num+n); if (n == 2) ans = num[1]-num[0]; else { if (n & 1) { a = num[0]==0 ? num[1]*10 : num[0]*10+num[1]; b = num[n-1]; for (int i = 0; i < (n-3)/2; ++ i) { a = 10*a + num[i+2]; b = 10*b + num[n-i-2]; } ans = a-b; } else { int mp = num[0]==0 ? 1 : 0; int md = num[mp+1] - num[mp]; for (int i = mp+1; i < n-1; ++ i) { if (num[i+1]-num[i] < md) md = num[i+1]-num[i]; } bool vis[10]; ans = 1000000000; for (int i = mp; i < n-1; ++ i) { if (num[i+1]-num[i] == md) { memset(vis, false, sizeof(vis)); vis[i] = vis[i+1] = true; a = num[i+1]; b = num[i]; for (int l=0,h=n-1; h>l; ) { while (l<n && vis[l]) l ++; while (h>0 && vis[h]) h --; if (l < h) { vis[l] = vis[h] = true; a = 10*a + num[l]; b = 10*b + num[h]; } } if (ans > a-b) ans = a-b; } } } } cout << ans << "\n"; } }
相关文章推荐
- Sicily 1239. Smallest Differencev
- sicily 1239. Smallest Differencev
- 1239. Smallest Differencev
- POJ2718-Smallest Difference-穷竭搜索
- POJ-----2718---Smallest Difference---暴力
- Smallest Difference(Poj2718)(枚举全排列next_Permutation)
- lintcode-medium-The Smallest Difference
- POj-2718 Smallest Difference--全排列next_permutation()的应用文章标题
- Smallest Difference-模拟
- the-smallest-difference
- poj 2718 Smallest Difference 【STL + dfs】
- [lintcode the-smallest-difference]最小差(python)
- The Smallest Difference
- POJ 2718 Smallest Difference(暴力枚举)
- SOJ 2868: find the smallest number
- POJ2718 Smallest Difference 【贪心+枚举】
- LintCode "The Smallest Difference"
- POJ 2718 Smallest Difference
- poj 2718 Smallest Difference 【dfs(全排列变形题)】
- #387 The Smallest Difference