1. 程式人生 > >6351 Beautiful Now(杭電多校第5場1002)

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;
}