Problem Description Anton has a positive integer n , however, it quite looks like a mess, so he wants to make it beautiful after k swaps of digits. Input The first line contains one integer T , indicating the number of test cases. Output For each test case, print in one line the minimum integer and the maximum integer which are separated by one space. 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 |
题目大意:给出一个数n,可以交换数中两个数字的位置,问交换k次以内得到的最下的数和最大的数
思路:用pos数组记录数组下标,运用全排列函数,得到每种下标的可能,然后判断;
具体看代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<map>
#include<queue>
#include<vector>
#include<stack>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=10;
int pos[N],k,n;
int a[N],cut;
int mark[N];
int judge()
{
memset(mark,0,sizeof(mark));//记住每次要清0
int tmp=0;
for(int i=0;i<cut;i++)
{
if(mark[i])//如果这个下标被标记就跳过下面继续循环
continue;
int e=0;//交换的次数
while(!mark[i])
{
e++;
mark[i]=1;
i=pos[i];//pos[i]为排列后的位置,i为排列前的位置
}
e--;//两两交换会多交换一次
tmp+=e;
if(tmp>k)
return 0;
}
return 1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,j,temp,maxx=0,minn=inf;
scanf("%d %d",&n,&k);
cut=0;
temp=n;
while(temp>0)
{
a[cut++]=temp%10;
temp/=10;
}
reverse(a,a+cut);
for(i=0;i<cut;i++)//记录下标
pos[i]=i;
do
{
if(a[pos[0]]!=0&&judge())//注意前缀不能是0
{
int ans=0;
for(i=0;i<cut;i++)
ans=ans*10+a[pos[i]];
maxx=max(ans,maxx);
minn=min(ans,minn);
}
}while(next_permutation(pos,pos+cut));//全排列函数,每次枚举每中下标的排列情况
printf("%d %d\n",minn,maxx);
}
return 0;
}