【链接】
http://acm.hdu.edu.cn/showproblem.php?pid=6351
【题意】
大意就是给你一个数n,求在最多k次得交换下,能够得到的最大的数和最小得数是多少,且数不能有前导0
【分析】
数的大小不超过1e9,也就是9位数字。
显然地,n个数至多交换n-1次能变成有序。
然后dfs+剪枝,有序地交换两个数.
【代码】
#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
char s[11];
int n[11];
int len;
int mi, ma;
int k;
void fmin() {
int a[11];
int cnt = 0;
for (int i = 0; i < len; i++) {
if (s[i]=='0')cnt++;
n[i] = s[i] - '0';
}
sort(n, n + len);
printf("%d", n[cnt]);
for (int i = 0; i < cnt; i++)printf("0");
for (int i = cnt + 1; i < len; i++)printf("%d", n[i]);
printf(" ");
}
void fmax() {
int a[11];
int cnt = 0;
for (int i = 0; i < len; i++) {
if (!s[i])cnt++;
n[i] = s[i] - '0';
}
sort(n, n + len);
for (int i = len - 1; i >= 0; i--) {
printf("%d", n[i]);
}
printf("\n");
}
int fun(int n[]) {
int res = 0;
for (int i = 0; i < len; i++) {
res = res * 10 + n[i];
}
return res;
}
void dfs(int tmp[],int cur, int num) {
if (cur ==len-1 || num == k) {
int u = fun(tmp);
mi = min(mi, u);
ma = max(ma, u);
return;
}
int u = fun(tmp);
mi = min(mi, u);
ma = max(ma, u);
for (int i = cur + 1; i < len; i++) {
if (cur == 0 && tmp[i] == 0)continue;
swap(tmp[cur], tmp[i]);
dfs(tmp,cur + 1, num + 1);
swap(tmp[cur], tmp[i]);
}
dfs(tmp,cur+1, num);
return;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%s%d", s, &k);
len = strlen(s);
mi = inf;
ma = 0;
if (k >= len - 1) {
fmin();
fmax();
}
else {
for (int i = 0; i < len; i++) {
n[i] = s[i] - '0';
}
dfs(n,0, 0);printf("%d %d\n", mi, ma);
}
}
}