POJ2718---Smallest Difference

来源:互联网 发布:js 跳转页面 target 编辑:程序博客网 时间:2024/06/06 02:15

题目大意:输入一串数字, 将其分为两组,每组随机搭配,组成一个整数,整数的不能以0开头,除非只有个位,求两个整数差的最小值
分析:DFS暴搜掉。很容易想到一个整数的位数为n/2,另一个为n-n/2时,差最小,所以,用next_permutation枚举。特殊情况需要注意,只有两个数字且其中一个为0,没注意这个,贡献了两个WA,晕死

代码:

#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;int a[15], vis[15], n, ans, aa, bb;void solve(int aa) {    int len = 0, flag = 1, b[15];    bb = 0;    for(int i = 0; i < n; i++)        if(!vis[i]) b[len++] = a[i];    for(int i = 0; i < len; i++) {        if(i == 0 && b[i] == 0) flag = 0;        bb = bb * 10 + b[i];    }    if(flag) ans = min(ans, abs(aa-bb));    while(next_permutation(b, b+len)) {         //next_permutation包含在algorithm中        bb = 0;        flag = 1;        for(int i = 0; i < len; i++) {            if(i == 0 && b[i] == 0) flag = 0;            bb = bb * 10 + b[i];        }        if(flag) ans = min(ans, abs(aa-bb));    }    return;}void dfs(int k, int res) {    if(k == n/2) {        solve(res);        return;    }    for(int i = 0; i < n; i++) {        if(!vis[i]) {            if(a[i] == 0 && k == 0) continue;            vis[i] = 1;            dfs(k+1, res*10+a[i]);            vis[i] = 0;        }    }    return;}int main() {    int kase;    scanf("%d", &kase);    getchar();    while(kase--) {        n = 0;        char ch;        memset(a, 0, sizeof(a));        memset(vis, 0, sizeof(vis));        while((ch = getchar()) != '\n') {            if(ch == ' ')                continue;            else a[n++] = ch - '0';        }        if(n == 2 && a[0] == 0) {               //当只有两个数字,且其中一个为0时,特殊处理            printf("%d\n", a[1]-a[0]);            continue;        }        ans = 1 << 30;        dfs(0, 0);        printf("%d\n", ans);    }    return 0;}
0 0