问题描述:
给你一些整数(0,1,2,......,9)且个数大于等于2小于等于10,它们互相组合算绝对值,让你求出最小的绝对值!
注意:
1. 0---9这些数每个最多出现一次
2. 不存在前导0的情况
题目链接:点击打开链接
思路:
假设长度为n那么只有两个数长度相等(或者长度差为1)时最小,我们就可以枚举出n/2个元素,再把剩下的组合找出来作差比较即可。
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int a[20], b[20], res, n;
bool booll[20];
void solve(int first){
int second = 0, k = 0;
for(int i = 0; i < n; i++)
if(!booll[i]){
b[k++] = a[i];
second = second*10 + a[i];
}
if(b[0] != 0 || k == 1)
res = min(res, abs(first - second));
while(next_permutation(b, b + k)){
second = 0;
for(int i = 0; i < k; i++)
second = second*10 + b[i];
if(b[0] != 0 || k == 1)
res = min(res, abs(first - second));
}
}
void DFS(int j, int first){
if(j == (n / 2)){//要想差的绝对值最小个数需要均分
solve(first);
return;
}
//枚举
for(int i = 0; i < n; i++){
if(!booll[i]){
if(j == 0 && n > 3 && a[i] == 0)
continue;
booll[i] = true;
DFS(j + 1, first*10 + a[i]);
booll[i] = false;
}
}
}
int main(){
int t;
scanf("%d", &t);
getchar();
while(t--){
n = 0;
char ch;
//借鉴某大牛的读取方式,很巧妙,学习了
while((ch = getchar()) != '\n'){
if(ch == ' ') continue;
a[n++] = ch - '0';
}
//当元素为10的时候答案只有一种,直接剥离出来
if(n == 10){
cout << "247" << endl;
continue;
}
res = INF;
memset(booll, false, sizeof(booll));
DFS(0, 0);
printf("%d\n", res);
}
return 0;
}