题目大意:输入一串数字, 将其分为两组,每组随机搭配,组成一个整数,整数的不能以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;
}