暴力:数字排列

题目:

现有n个k位的数字,你的任务是重新安排数字每一位的位置,使得重新安排后这n个数字中最大的数字和最小的数字之差的绝对值最小,对于每一位的调整是相对于所有的数字的,例如有3个数字1234、4321和7890,重新安排的方案是交换第二位和第三位,则3个数字变为1324、4231和7980。

Input
输入包括多组样例,每组样例包括多行。每组样例的第一行包括2个整数n和k,分别代表数字的个数和位数(1 ≤ n, k ≤  8),接下来的的n行包括n个k位的数字,允许调整后的数字有前导0(例如000123代表123)。

Output
每组数据输出一个整数,为调整后最大数字与最小数字之间的最小差值。

Sample Input
3 3
010
909
012
6 4
5237
2753
7523
5723
5327
2537

Sample Output
3
2700

Hint
第二组样例可以将原顺序( 1,2,3,4) 调整为(3,1,4,2),则第二个数字变为5237,第三个数字变为2537,分别为这样变换后的最大值和最小值,可以验证这样变换后的差值2700为最小差值


理解:
对于给出的所有数要求交换方式一样,因此我是用b[n]=n的方式作为字符串a[i]的下标,然后对b[n]使用全排列函数(当然要计算所有排列的值–阶乘),即a[i][b[n]](这样可以做到这个数上所有位进行全排列的情况),这样计算出每个数然后排序取最大最小的差并不断更新,得出最后的最小的最大最小的差就OK。


代码如下:

#include 
#include 
#include 
#include 
using namespace std;
int main()
{
    int n, k;
    while(cin >> n >> k)
    {
        int mn = 0, mx = 0, mi = 1, cha = 100000000;
        string a[9];
        int b[9];
        for(int i = 0; i < n; i++)
            cin >> a[i];
        for(int i = 0; i < k; i++)
            b[i] = i;
        for(int i = 1; i <= k; i++)
        {
            mi *= i;
        }
        for(int i = 0; i < mi; i++)
        {
            int c[9];
            for(int j = 0; j < 9; j++)
                c[j] = 0;
            for(int j = 0; j < n; j++)
            {
                for(int p = 0; p < k; p++)
                {
                    c[j] = c[j] * 10 + a[j][b[p]] - '0';
                    //cout << c[j] << endl;
                }
                //cout << endl;
            }
            sort(c, c + n);
            if(cha > c[n-1] - c[0])
                cha = c[n-1] - c[0];
            next_permutation(b, b + k);
        }
        cout << cha << endl;
    }
    return 0;
}

你可能感兴趣的:(枚举)