hdu 6351 Beautiful Now(BFS+暴力)

hdu 6351 Beautiful Now

http://acm.hdu.edu.cn/showproblem.php?pid=6351

Anton has a positive integer nn, however, it quite looks like a mess, so he wants to make it beautiful after kk swaps of digits. 
Let the decimal representation of nn as (x1x2⋯xm)10(x1x2⋯xm)10 satisfying that 1≤x1≤91≤x1≤9, 0≤xi≤90≤xi≤9 (2≤i≤m)(2≤i≤m), which means n=∑mi=1xi10m−in=∑i=1mxi10m−i. In each swap, Anton can select two digits xixi and xjxj (1≤i≤j≤m)(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 kk swaps?

Input

The first line contains one integer TT, indicating the number of test cases. 
Each of the following TT lines describes a test case and contains two space-separated integers nn and kk. 
1≤T≤1001≤T≤100, 1≤n,k≤1091≤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

题意:多组数据。给你一个范围在1e9以内的数,将数的两位之间交换给定次数,求交换后可以得到的最大值和最小值。

分析:这道题不能用贪心!这道题不能用贪心!这道题不能用贪心!

错误 / 待修改的思路是:用数组记录每一位,确定按最大(小)值排列好的顺序,每次从左往右找不是最大(小)值的位,从右往左找等于最大(小)值的位并交换。这样可以举出反例(我也是从网上大神博客看到的):970979 2。因为用贪心的思路会求得970979 -> 990977 -> 999077。而实际在第一次交换时出错,正确交换顺序为:970979 -> 990779 -> 999770 ( > 999077 ! )

从而我们可以看出,虽然我们每次交换需要把从左往右“不是最大值的位”变成“最大值的位”,但是如果有多位相等(比如970979的从左往右第四位和第六位都是9),这时候我们无法贪心确定哪种情况最优,所以两条路都需要走下去!

用BFS思想,暴力把经过k次交换可能的结果都加入队列,用一个数组保存最大或小值,当depth==k+1时跳出即可。

AC代码:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
#define ll long long


char num[15],maxn[15],minn[15];
char ans[15],ans2[15];
int time, l;
struct Change{
    char result[15];
    int depth;
};

void bfsmin(){
    Change x,y;
    x.depth = 0;
    memcpy(x.result,num,sizeof(num));
    queue<Change> q;
    q.push(x);
    memcpy(ans,x.result,sizeof(x.result));
    while(!q.empty()){
        x = q.front();
        //cout << ":" << x.result << " " << x.depth << endl;
        q.pop();
        if(x.depth==time+1)break;
        //cout << "?" << memcmp(ans,x.result,sizeof(x.result)) << endl;
        if(memcmp(ans,x.result,sizeof(x.result))>0){
            memcpy(ans,x.result,sizeof(x.result));
        }
        y.depth = x.depth+1;
        int i;
        for(i=0;i<l;i++){
            if(minn[i]!=x.result[i])
                break;
        }
        if(i==l)continue;
        for(int j=i;j<l;j++){
            if(x.result[j]==minn[i]){
                memcpy(y.result,x.result,sizeof(x.result));
                char a=y.result[j];
                y.result[j]=y.result[i];
                y.result[i]=a;
                q.push(y);
            }
        }
    }
}

void bfsmax(){
    Change x,y;
    x.depth = 0;
    memcpy(x.result,num,sizeof(num));
    queue<Change> q;
    q.push(x);
    memcpy(ans2,x.result,sizeof(x.result));
    while(!q.empty()){
        x = q.front();
        //cout << ":" << x.result << " " << x.depth << endl;
        q.pop();
        if(x.depth==time+1)break;
        //cout << "?" << memcmp(ans,x.result,sizeof(x.result)) << endl;
        if(memcmp(ans2,x.result,sizeof(x.result))<0){
            memcpy(ans2,x.result,sizeof(x.result));
        }
        y.depth = x.depth+1;
        int i;
        for(i=0;i<l;i++){
            if(maxn[i]!=x.result[i])
                break;
        }
        if(i==l)continue;
        for(int j=i;j<l;j++){
            if(x.result[j]==maxn[i]){
                memcpy(y.result,x.result,sizeof(x.result));
                char a=y.result[j];
                y.result[j]=y.result[i];
                y.result[i]=a;
                q.push(y);
            }
        }
    }
}

int cmp(char a,char b){
    return a>b;
}

int main(){
    int t;
    cin >> t;
    while(t--){
        cin >> num >> time;
        l = strlen(num);
        memcpy(maxn,num,sizeof(num));
        memcpy(minn,num,sizeof(num));
        sort(minn,minn+l);
        int count;
        for(count=0;count<l;count++){
            if(minn[count]!='0')
                break;
        }
        if(l!=1 && count<l){
            char a = minn[count];
            minn[count] = minn[0];
            minn[0] = a;
        }
        sort(maxn,maxn+l,cmp);
        bfsmin();
        bfsmax();
        cout << ans << " " << ans2 << endl;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值