給一個數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