POJ 2718: Smallest Difference
http://poj.org/problem?id=2718
题目的大致意思:
1.给一串不重复的数字(单个数字,0-9)
2.这串数字没有重复
3.这些数字已经按照升序排序
4.把这串数字顺序打乱,中间选一个位置把这串数字一拆二,形成两个整数,求这两个整数相减绝对值的最小值
思路:
这里我用穷举法
1.得到数字串的全排列(用next_permutation函数。实在有闲情可以用深度搜索来一遍全排列)
2.把数字从中间一分为二,计算差的绝对值
注意点:
1.拆数字串只需要length/2进行拆分(也就是说无需从第二个数字、第三个数字。。。这样一位位拆。因为length/2这样的拆法保证两个数字位数相等或者只差1位,绝对值最小的结果肯定在这里,不会在那些两个数字差2位的排列中)
2.拆分的两个数字如果不是0,则不能以0开始。比如012这种是不行的
3.输入测试用例个数的那一行结尾可能有空行
1 #include <stdio.h> 2 #include <algorithm> 3 using namespace std; 4 5 int arr[10]; //输入数组 6 7 //返回较小值 8 int min(int a, int b) 9 { 10 return a < b ? a : b; 11 } 12 13 int main() 14 { 15 int caseCnt; //案例数 16 while (scanf("%d", &caseCnt) != EOF) 17 { 18 char tmp[200]; 19 gets(tmp); //吃空行 20 21 while (caseCnt--) 22 { 23 //输入 24 char c; 25 int length = 0; //串长度 26 while (c = getchar()) 27 { 28 if (c == '\n') 29 break; 30 else if (c >= '0'&&c <= '9') 31 arr[length++] = c - '0'; 32 } 33 34 //处理 35 int div = length / 2; //分割的地方,长度的一半 36 int ans = 0x7fffffff; //结果 37 38 do 39 { 40 //第一个数 41 int iFirst = 0; 42 if (arr[0] == 0 && div > 1) //长度大于1,不允许先导0 43 continue; 44 for (int i = 0; i < div; i++) 45 { 46 iFirst = iFirst * 10 + arr[i]; 47 } 48 49 //第二个数 50 int iSecond = 0; 51 if (arr[div] == 0 && length - div>1) //长度大于1,不允许先导0 52 continue; 53 for (int i = div; i < length; i++) 54 { 55 iSecond = iSecond * 10 + arr[i]; 56 } 57 58 ans = min(ans, abs(iFirst - iSecond)); 59 } while (next_permutation(arr, arr + length)); //arr数组全排列 60 61 printf("%d\n", ans); 62 } 63 } 64 return 0; 65 }