POJ 2718-Smallest Difference [dfs] 《挑战程序设计竞赛》2.1

来源:互联网 发布:unity3d 粒子系统闪电 编辑:程序博客网 时间:2024/06/10 16:51

题目链接: 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 100using 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;} 
0 0