版权声明:布呗之路的守望者 https://blog.csdn.net/hypHuangYanPing/article/details/81876966
/**
HDU 6351 B : Beautiful Now
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6351
题意:给你两个数字 n k 窝们可以选择交换数字n上任意两个数位上的数字 使得得到的数字最大和最小;
输出最大值和最小值;
分析:其实也算是一种暴力的走法吧 仔细点你会发现 其实交换的话最多就交换它的位数减-1
那么我们可以对于这样的性质进行暴力求解 可以用两个队列 一个存储当前元素的值 一个存储当前的步数(<= 当前的最短步数);
*****tricks*****
对于每一次查询最大值和最小值得时候 最后需要将交换后的值进行复原
因为暴力当前存在的可能不是最优的,因为我们只走了一步的情况 对于以后的状态 有step+1来解决
*/
#include<bits/stdc++.h>
using namespace std;
map<int,bool>mp;
queue<int>team;
queue<int>bs;//步数
void solved(){
int n,k;scanf("%d %d",&n,&k);
while(!team.empty()) team.pop();
while(!bs.empty()) bs.pop();
mp.clear();
team.push(n),bs.push(0);
int minn=n,maxn=n;
int len=0,a[11];
int pt=n,nk=0;
if(pt==0) nk=1;
else while(pt) nk+=1,pt/=10;
nk--,k=min(k,nk);
while(!team.empty()){
int num=team.front(),step=bs.front();
team.pop();bs.pop();
maxn=max(maxn,num),minn=min(minn,num);
if(step==k) continue;
int pt=num;
len=nk;
while(pt) a[len--]=pt%10,pt/=10;
len=nk;
for(int i=0;i<=len;i++){
int pos=-1,maxn=a[i];
for(int j=i+1;j<=len;j++){
if(i==0&&a[j]==0) continue;
if(maxn<a[j]) maxn=a[j],pos=j;
else if(maxn==a[j]&&pos!=-1) pos=j;
}
if(pos==-1) continue;
swap(a[i],a[pos]);
int nb=0;
for(int k=0;k<=len;k++) nb=nb*10+a[k];
if(mp.find(nb)==mp.end()){
mp[nb]=true;
team.push(nb);
bs.push(step+1);
}
swap(a[pos],a[i]);
}
for(int i=0;i<=len;i++){
int pos=-1,maxn=a[i];
for(int j=i+1;j<=len;j++){
if(i==0&&a[j]==0) continue;
if(maxn>a[j]) maxn=a[j],pos=j;
else if(maxn==a[j]&&pos!=-1) pos=j;
}
if(pos==-1) continue;
swap(a[i],a[pos]);
int nb=0;
for(int k=0;k<=len;k++) nb=nb*10 + a[k];
if(mp.find(nb)==mp.end()){
mp[nb] = true;
team.push(nb);
bs.push(step+1);
}
swap(a[pos],a[i]);
}
}
printf("%d %d\n",minn,maxn);
}
int main(){
int t;scanf("%d",&t);
while(t--) solved();
return 0;
}