B - Beautiful Now
题意:有一个数n和一个数k,通过交换n中的任意两个位置,(交换次数小于等于k),求能形成的最大数和最小数
Input
The first line contains one integer T, indicating the number of test cases.
Each of the following T lines describes a test case and contains two space-separated integers
n and k.
1≤T≤100, 1≤n,k≤10e9.
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
思路:比赛时是用贪心做的,一直WA。赛后发现970970 2这组样例不对,应该用全排列,把所有情况列出来,再找出交换次数,找符合次数的最大值和最小值。
我们可以对每个数所在的位置进行全排列,注意一点!要把字符串对应的数值存到一个int型的数组里,否则每次进行s[ i ] - ’ 0 '会T
代码:
#include <map>
#include <list>
#include <deque>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define inf 0x3f3f3f3f
#define mod 1000000009
using namespace std;
typedef long long ll;
int main()
{
int T;
ll k;
char s[20];
ll maxx,minn;
int flag[20], vis[20] ,a[20];
scanf("%d", &T);
while(T--)
{
scanf(" %s",s);
scanf("%lld",&k);
int len = strlen(s);
for(int i=0; i<len; i++){
flag[i] = i;
a[i] = s[i] -'0';
}
maxx = -1;
minn = inf;
do
{
int ans =0,t,flag1=0;
for(int i=0;i<len;i++)
vis[i] = 0;
for(int i=0; i<len; i++)
{
if(vis[i] == 0)
{
t = 0;
while(vis[i] == 0)
{
t++;
vis[i] = 1;
i=flag[i];
}
ans +=t-1;
}
if(ans > k){
flag1 =1;
break;
}
}
if(flag1 == 1)
continue;
if(ans <= k)
{
if(a[flag[0]] != 0){
ll K=0;
for(int i=0; i<len; i++)
{
K = K + (a[flag[i]]);
if(i != len-1)
K *=10;
}
if(K > maxx)
maxx = K;
if(K < minn)
minn = K;
}
}
}while(next_permutation(flag,flag+len));
printf("%lld %lld\n",minn,maxx);
}
return 0 ;
}