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

猜你喜欢

转载自blog.csdn.net/Vitamin_R/article/details/81482702