挑战程序设计竞赛 2.1章习题 poj 2718 Smallest Difference dfs

Description

Given a number of distinct decimal digits, you can form one integer by choosing a non-empty subset of these digits and writing them in some order. 
The remaining digits can be written down in some order to form a second integer. Unless the resulting integer is 0, the integer may not start with the digit 0. For example, if you are given the digits 0, 1, 2, 4, 6 and 7, you can write the pair of integers 10 and 2467.
Of course, there are many ways to form such pairs of integers: 210 and 764, 204 and 176, etc.
The absolute value of the difference between the integers in the last pair is 28, and it turns out that no other pair formed by the rules above can achieve a smaller difference. Input The first line of input contains the number of cases to follow. For each case, there is one line of input containing at least two but no more than 10 decimal digits.
(The decimal digits are 0, 1, ..., 9.) No digit appears more than once in one line of the input. The digits will appear in increasing order, separated by exactly one blank space. Output For each test case, write on a single line the smallest absolute difference of two integers that can be written from the given digits as described by the rules above. Sample Input 1 0 1 2 4 6 7 Sample Output 28

地址 https://vjudge.net/problem/POJ-2718

题意大概是给出 不重复的0~9的数字 要求组合成两个数字 差值最小

输出最小的差值作为答案

考点是DFS穷举遍历, 给出的数字的所有组合 然后分为长度接近或者长度相同的数字 计算差值

没有使用stl中的库函数 自己编写DFS进行的穷举所有数列组合

注意  如果数字有两位以上,0 不能作为数字开头

数字全排列可以参考这篇题解 

LeetCode 046. 全排列 dfs 和 dfs_swap

视频地址  https://www.bilibili.com/video/BV1Pp4y1B7on

 

代码

 
#include <iostream>
#include <algorithm>
#include <vector>
#include <algorithm>

using namespace std;

/*
1
0 1 2 4 6 7

28
*/
int totallen;
char arr[50];
int n; int ans = 99999999;

void calc()
{
    int len = totallen / 2;

    int a = 0; int b = 0;
    if (arr[0] == '0' && len > 1)  return;
    if (arr[len] == '0' && (totallen - len) > 1) return;

    for (int i = 0; i < len; i++) {
        a += arr[i] - '0';
        a = a * 10;
    }
    a = a / 10;

    for (int i = len; i < totallen; i++) {
        b += arr[i] - '0';
        b = b * 10;
    }
    b = b / 10;


    ans = min(ans, abs(b - a));
    return;
}

//产生输入数组的不同组合 进行差值比较
void dfs(int start) {
    if (start >= totallen) {
        calc();
        return;
    }

    for (int i = start ; i < totallen; i++) {
        swap(arr[start], arr[i]);
        dfs(start+1);
        swap(arr[start], arr[i]);
    }
}

int solve() {
    //产生该arr可能的各种组合 然后计算组合差值
    dfs(0);
    return 0;
}

int main()
{
    char tmp='\0';
    scanf("%d",&n);
    while(tmp != '\n') scanf("%c", &tmp);

    while (n--) {
        memset(arr, 0, sizeof arr);
        totallen = 0; ans = 99999999;
        while (totallen < 50) {
            scanf("%c",&tmp);
            if (tmp != ' '&& tmp != '\r'&& tmp != '\n') {
                arr[totallen] = tmp; totallen++;
            }
            if (tmp == '\n') break;
        }

        solve();
        printf("%d\n",ans);
    }


    return 0;
}

 

上一篇:LeetCode66 - 加一


下一篇:JS逆向-抠代码的第一天