6351 Beautiful Now(杭電多校第5場1002)
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;
}