(全排列)Smallest Difference (poj2718)

题目:

Description - 题目描述
给定若干位十进制数,你可以通过选择一个非空子集并以某种顺序构建一个数。剩余元素可以用相同规则构建第二个数。除非构造的数恰好为0,否则不能以0打头。

举例来说,给定数字0,1,2,4,6与7,你可以写出10和2467。当然写法多样:210和764,204和176,等等。最后一对数差的绝对值为28,实际上没有其他对拥有更小的差。
Input - 输入
输入第一行的数表示随后测试用例的数量。
对于每组测试用例,有一行至少两个不超过10的十进制数字。(十进制数字为0,1,…,9)每行输入中均无重复的数字。数字为升序给出,相隔恰好一个空格。
Output - 输出
对于每组测试用例,输出一个以上述规则可获得的最小的差的绝对值在一行。
Sample Input - 输入样例
1
0 1 2 4 6 7
Sample Output - 输出样例
28

分析与解答:

就是利用next_permutation这个函数生成这组数的全排列,然后把全排列分开看,每个组成一组数,而且a[0]和a[mid]都不为零,这是因为两组数的第一个位置上的数数不是零。
只需判断那两组数形成的数的差是不是最小的,最后输出那个最小值即可

参考代码:
https://www.cnblogs.com/Jadon97/p/6763634.html

#include<bits/stdc++.h> 
using namespace std;
char aa[20];
int a[20];
int cnt, mid, ans;
int main()
{
    int t;
    scanf("%d", &t);
    getchar();
    while(t--)
    {
        cnt = 0;
        int t;
        while((t = getchar()) != '\n')
        {
            if(t != ' ')
            {
                aa[cnt] = t;
                cnt++;
            }
        }

        int mid = cnt/2;
        ans = 1e9;
        if(cnt == 2)
        {
            printf("%d\n",aa[1]-aa[0]);
            continue;
        }
        for(int i = 0; i < cnt; i++)
        {
            a[i] = aa[i] - '0';
        }
        while(a[0] ==0)
            next_permutation(a,a+cnt);//第一组数的第一个数不能为0
        do
        {
            if(a[mid])//第二组数的第一个数不能为0 
            {
                int t1=0,t2=0;
                for(int i=0;i<mid;++i)
                    t1=t1*10+a[i];
                for(int i=mid;i<cnt;++i)
                    t2=t2*10+a[i];
                ans=min(ans,abs(t1-t2));
                }

        }while(next_permutation(a,a+cnt));
        printf("%d\n",ans);


    }
}

猜你喜欢

转载自blog.csdn.net/qq_40828914/article/details/81489002