HDU 6351 B : Beautiful Now

版权声明:布呗之路的守望者 https://blog.csdn.net/hypHuangYanPing/article/details/81876966
/**
HDU 6351 B : Beautiful Now
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6351

题意:给你两个数字 n k  窝们可以选择交换数字n上任意两个数位上的数字 使得得到的数字最大和最小;
输出最大值和最小值;
分析:其实也算是一种暴力的走法吧 仔细点你会发现 其实交换的话最多就交换它的位数减-1
那么我们可以对于这样的性质进行暴力求解 可以用两个队列 一个存储当前元素的值 一个存储当前的步数(<= 当前的最短步数);
*****tricks*****
对于每一次查询最大值和最小值得时候 最后需要将交换后的值进行复原 
因为暴力当前存在的可能不是最优的,因为我们只走了一步的情况 对于以后的状态 有step+1来解决 
*/

#include<bits/stdc++.h>
using namespace std;

map<int,bool>mp;
queue<int>team;
queue<int>bs;//步数

void solved(){
    int n,k;scanf("%d %d",&n,&k);
    while(!team.empty()) team.pop();
    while(!bs.empty()) bs.pop();

    mp.clear();
    team.push(n),bs.push(0);
    int minn=n,maxn=n;
    int len=0,a[11];

    int pt=n,nk=0;
    if(pt==0) nk=1;
    else while(pt) nk+=1,pt/=10;
    nk--,k=min(k,nk);



    while(!team.empty()){

        int num=team.front(),step=bs.front();
        team.pop();bs.pop();
        maxn=max(maxn,num),minn=min(minn,num);
        if(step==k) continue;

        int pt=num;
        len=nk;
        while(pt) a[len--]=pt%10,pt/=10;


        len=nk;
        for(int i=0;i<=len;i++){

            int pos=-1,maxn=a[i];
            for(int j=i+1;j<=len;j++){
                if(i==0&&a[j]==0) continue;
                if(maxn<a[j]) maxn=a[j],pos=j;
                else if(maxn==a[j]&&pos!=-1) pos=j;
            }

            if(pos==-1) continue;
            swap(a[i],a[pos]);
            int nb=0;
            for(int k=0;k<=len;k++) nb=nb*10+a[k];

            if(mp.find(nb)==mp.end()){
                mp[nb]=true;
                team.push(nb);
                bs.push(step+1);
            }
            swap(a[pos],a[i]);
        }


        for(int i=0;i<=len;i++){
            int pos=-1,maxn=a[i];
            for(int j=i+1;j<=len;j++){
                if(i==0&&a[j]==0) continue;
                if(maxn>a[j]) maxn=a[j],pos=j;
                else if(maxn==a[j]&&pos!=-1) pos=j;
            }
            if(pos==-1) continue;
            swap(a[i],a[pos]);
            int nb=0;
            for(int k=0;k<=len;k++) nb=nb*10 + a[k];
            if(mp.find(nb)==mp.end()){
                mp[nb] = true;
                team.push(nb);
                bs.push(step+1);
            }
            swap(a[pos],a[i]);
        }
    }
    printf("%d %d\n",minn,maxn);
}

int main(){
    int t;scanf("%d",&t);
    while(t--) solved();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hypHuangYanPing/article/details/81876966