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.
Let the decimal representation of n as (x1x2⋯xm)10 satisfying that 1≤x1≤9, 0≤xi≤9 (2≤i≤m), which means n=∑mi=1xi10m−i. In each swap, Anton can select two digits xi and xj (1≤i≤j≤m) and then swap them if the integer after this swap has no leading zero.
Could you please tell him the minimum integer and the maximum integer he can obtain after k swaps?
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≤109.
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(1<=N<=1e9),k(1<=k<=1e9),求对N的任意两位数交换至多k次能得到的最小与最大的数,每一次交换之后不能出现前导零。
分析:
多校的时候想过dfs爆搜,觉着太麻烦也没什么思路。后来又想了讨论数位关系。嗯~也没有什么想法。
看了 dls 写的博客,dfs...过了。数位全排列...过了。果然是自己太菜。
再次见识到了C++内置函数的强大。
思路:
对下标进行全排列,判断交换次数是否合理,判断有无前导零,找出合法的最大最小值,复杂度的话,肯定不会超的就是了
(主要是如果我发出来还算错了岂不是很尴尬哈哈)
AC代码:
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();return x*f;}
//ll qpow(ll x, ll y, ll mod){ll s=1;while(y){if(y&1)s=s*x%mod;x=x*x%mod;y>>=1;}return s;}
ll qpow(ll a, ll b){ll s=1;while(b>0){if(b&1)s=s*a;a=a*a;b=b>>1;}return s;}
int vis[10], pos[10], val[10];
ll k, n;
int len;
int judge()
{
int cnt=0 ; ms(vis, 0);
for(int i=0;i<len;i++){
if(vis[i]==0)
{
int tmp=0;
while(!vis[i]){
tmp++;
vis[i]=1;
i=pos[i];
}tmp--; cnt+=tmp;
if(cnt>k) return 0;
}
}
return cnt;
}
int main()
{
int T;scanf("%d", &T);
while(T--)
{
scanf("%lld%lld", &n, &k);
ll t=n; len=0;
while(t){
val[len++]=t%10;
t/=10;
}
reverse(val, val+len); //一定要反转,因为上面入的时候是倒着入的
for(int i=0;i<len;i++)
pos[i]=i;
ll minn=n, maxx=n;
do{
if(val[pos[0]]!=0 && judge()){
ll tmp =0;
for(int i=0;i<len;i++){
tmp*=10;
tmp+=val[pos[i]];
}
if(tmp<minn) minn=tmp;
if(tmp>maxx) maxx=tmp;
}
}while(next_permutation(pos, pos+len));//C++函数依旧强大
printf("%lld %lld\n", minn, maxx);
}
return 0;
}