HDU-6351 Beautiful Now 全排列暴力

时间:2020-04-25
本文章向大家介绍HDU-6351 Beautiful Now 全排列暴力,主要包括HDU-6351 Beautiful Now 全排列暴力使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Beautiful Now

题意

给出一个最大为10^9的数字n,以及一个k,你最多交换n中任意两个位置的数字k次,问形成的最大数字和最小数字。

思路

看到这题,我靠这题暴力交换一下,不难啊,咋没人做。。

后来发现是我菜了,贪心写完成功WA了,比如这个样例970970 2,最小值不对。

正解是暴力,进行全排列,检验某个排列是否合法。

n最大是10^9所以枚举次数最多为9!(362880)*9,复杂度可以接受。

(昨天被自己傻到了,搞了两次全排列一个求最大值一个求最小值。。。)

代码

//#include<bits/stdc++.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const double eps=1e-14;

int arr[N],brr[N],crr[N],pos[10];
int cnt,x,k;
int check()
{
    for(int i=1;i<=cnt;i++)
    {
        brr[i]=crr[i];
        pos[brr[i]]=i;
    }
    int ans=0;
    for(int i=1;i<=cnt;i++)
    {
        if(brr[i]!=i)
        {
            ans++;
            if(ans>k) return 0;
            pos[brr[i]]=pos[i];
            swap(brr[i],brr[pos[i]]);
        }
    }
    return ans<=k;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        cnt=0;
        scanf("%d%d",&x,&k);
        int maxn=x,minn=x;
        while(x)
        {
            arr[++cnt]=x%10;
            x/=10;
        }
        for(int i=1; i<=cnt; i++)
            crr[i]=i;
        do
        {
            if(arr[crr[cnt]]==0||(!check()))
                continue;
            int tmp=0;
            for(int i=cnt; i; i--)
                tmp=tmp*10+arr[crr[i]];
            minn=min(minn,tmp);
            maxn=max(maxn,tmp);
        }
        while(next_permutation(crr+1,crr+1+cnt));
        printf("%d %d\n",minn,maxn);
    }
    return 0;
}

博客

原文地址:https://www.cnblogs.com/valk3/p/12773437.html