题目链接: POJ 2718-Smallest Difference
题目大意:
给定一些单独的十进制数字,将其分为2组, 并组成2个十进制数字, 计算两者之差。找出这样的最小的 差值的绝对值。
比如给定 0, 1, 2, 4, 6, 7 可以分成2组,组成数字10、764, 或者 204 、176, 或者10, 2467…… 可以找到最小的差值为abs(204-176) = 28
输入格式:
第一行一个n整数表示下面有n组测试数据
接下来1~n+1行每行为一组测试数据, 有2~10个由空格分开的一位十进制数字
输出格式:
一个数字, 表示最小的差值
题解:
首先给输入的数字进行全排列, 然后再分成两组, 计算差值, 求出最小的差值。
分组不需要枚举所有的情况, 只要把两组分成个数相等或者个数只相差1的两组即可。
分成的两组中, 如果由一组长度大于1且以0开头, 则不合法, 跳过。
测试数据为0 1 2 3 4 5 6 7 8 9 的时候会超时, 无奈之下打个表。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define MAXN 100
using namespace std;
char str[MAXN];
char *s = str;
int a[10];
int perm[10];
bool f[10];
int k;
int number(int begin, int end) {
int num = 0;
for (int i = begin; i <= end; i++) {
num *= 10;
num += perm[i];
}
return num;
}
int dfs(int step) {
if (step == k) {
int x, y, m;
m = 0x3f3f3f3f;
int i = k/2;
if ((perm[0] == 0 && i>1)|| (perm[i] == 0 && i < k-1)) return m;
x = number(0, i-1);
y = number(i, k-1);
int tmp = abs(x-y);
m = tmp < m ? tmp : m;;
return m;
}
int m = 0x3f3f3f3f;
for (int i = 0; i < k; i++) {
if (!f[i]) {
f[i] = true;
perm[step] = a[i];
int tmp = dfs(step+1);
m = tmp < m ? tmp : m;
f[i] = false;
}
}
return m;
}
int main() {
int t;
scanf("%d", &t);
s = fgets(s, 100, stdin);
for (int i = 0; i < t; i++) {
memset(a, 0, sizeof(a));
memset(f, false, sizeof(f));
memset(perm, 0, sizeof(perm));
k = 0;
s = str;
s = fgets(s, 100, stdin);
for (; s != NULL; s = ((s = strchr(s, ' ') )== NULL ? NULL : s+1)) {
a[k++] = *s - '0';
}
int ans;
if (k == 10) ans = 247;
else ans = dfs(0);
printf("%d\n", ans);
}
return 0;
}