版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/V5ZSQ/article/details/82453397
Description
给一个数字 ,可以交换 次其中任意两个位置的数字,问交换后该数字的最大值和最小值
Input
第一行一整数 表示用例组数,每组用例输入两个整数
Output
输出最小值和最大值
Sample Input
5
12 1
213 2
998244353 1
998244353 2
998244353 3
Sample Output
12 21
123 321
298944353 998544323
238944359 998544332
233944859 998544332
Solution
暴搜,以求最大值为例,从高到低按位考虑,如果当前位不是剩余数字的最大值,则将当前位与后面的最大值依次交换往下深搜,剪枝为操作数不会超过 长度减一
Code
#include<cstdio>
#include<algorithm>
using namespace std;
int T,n,k,a[11],m,ans;
void dfs_max(int pos,int num)
{
if(pos==m)
{
int res=0;
for(int i=1;i<=m;i++)res=10*res+a[i];
ans=max(ans,res);
return ;
}
int mx=0;
for(int i=pos;i<=m;i++)mx=max(mx,a[i]);
if(a[pos]==mx||num==k)dfs_max(pos+1,num);
else
{
for(int i=pos+1;i<=m;i++)
if(a[i]==mx)
{
swap(a[pos],a[i]);
dfs_max(pos+1,num+1);
swap(a[pos],a[i]);
}
}
}
void dfs_min(int pos,int num)
{
if(pos==m)
{
int res=0;
for(int i=1;i<=m;i++)res=10*res+a[i];
ans=min(ans,res);
return ;
}
int mn=10,cnt=0;
if(pos==1)
{
for(int i=pos;i<=m;i++)
if(a[i])mn=min(mn,a[i]);
}
else
{
for(int i=pos;i<=m;i++)
mn=min(mn,a[i]);
}
if(a[pos]==mn||num==k)dfs_min(pos+1,num);
else if(num<k)
{
for(int i=pos+1;i<=m;i++)
if(a[i]==mn)
{
swap(a[pos],a[i]);
dfs_min(pos+1,num+1);
swap(a[pos],a[i]);
}
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
int nn=n;
m=0;
while(nn)a[++m]=nn%10,nn/=10;
reverse(a+1,a+m+1);
k=min(k,m-1);
ans=n;
dfs_min(1,0);
printf("%d ",ans);
nn=n;
m=0;
while(nn)a[++m]=nn%10,nn/=10;
reverse(a+1,a+m+1);
ans=n;
dfs_max(1,0);
printf("%d\n",ans);
}
return 0;
}