给一个数n,在m次交换位置(可以自己和自己swap)之后,分别求出得到的最小值和最大值。
(X)贪心:min(每次把右边最小的值与最前面比它大的值交换)max(每次把最右边最小的值与最前面比它小的值交换)最后特判右边交换到左边的值如果一样,那么交换到右边的值按小到大排列(大到小排列)太年轻
ac做法:dfs+剪枝 || 根据全排列求(没写)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 20;
int t, n, m, cnt, mn, mx;
int a[N], num[N];
int _pow(int x, int y)///快速幂
{
int ans = 1;
while(y){
if(y&1) ans *= x;
x *= x;
y >>= 1;
}
return ans;
}
void g_num(int b)///数字转成数组形式
{
cnt = 0;
while(b){
num[cnt++] = b%10;
b /= 10;
}
for(int i=0; i<cnt/2; i++){///得交换一下位置好处理
int swp = num[i];
num[i] = num[cnt-i-1];
num[cnt-i-1] = swp;
}
}
void copyn(int le[], int ri[])///交换俩数组的值
{
for(int i=0; i<cnt; i++){
le[i] = ri[i];
}
}
int g_int()///数组转整数
{
int sum = 0;
for(int i=0; i<cnt; i++){
sum += a[i]*_pow(10, cnt-i-1);
}
if(a[0] == 0) return inf;///除去前导0
return sum;
}
void dfs1(int k)///最小值dfs
{
mn = min(mn, g_int());///不到m次交换已经得到结果
if(k==m || k==cnt-1){
return;
}
for(int i=k; i<cnt; i++){
for(int j=i+1; j<cnt; j++){
if(a[j] < a[i]){///已经得到结果的情况下不迭代
swap(a[j], a[i]);
dfs1(k+1);
swap(a[j], a[i]);
}
}
}
}
void dfs2(int k)///最大值dfs
{
int tmp = g_int();
if(tmp == inf) tmp = 0;
mx = max(mx, tmp);
if(k==m || k==cnt-1){
return;
}
for(int i=k; i<cnt; i++){
for(int j=i+1; j<cnt; j++){
if(a[j] > a[i]){
swap(a[j], a[i]);
dfs2(k+1);
swap(a[j], a[i]);
}
}
}
}
int main()
{
scanf("%d", &t);
while(t --){
mx = 0;
mn = inf;
scanf("%d%d", &n, &m);
g_num(n);
copyn(a, num);
dfs1(0);
printf("%d ", mn);
copyn(a, num);///a搜索之后得重新copy num数组的值
dfs2(0);
printf("%d\n", mx);
}
return 0;
}
//10
//12 1
//213 2
//998244353 1
//998244353 2
//998244353 3
//232111 2
//12 2
//21 2
//9340 6
//722985769 4