HDU-6531-Beautiful Now( 2018 Multi-University Training Contest 5)(dfs)

HDU-6531-Beautiful Now( 2018 Multi-University Training Contest 5)(dfs)

传送门

题意:给你一个数n,每次可以选择n的两个位并交换它们的位置,问交换k次之后,n的最小值和最大值分别是多少(1<=n,k<=1e9)
思路:首先想到当k大于等于n的位数-1时,该数位数能交换一遍,此时应该是所有排列的最小值和最大值(注意前导0),接着贪心考虑,到某一位时,选择后面的最大的数与之交换,但是这样会出现问题,例如3299,交换一次是9293,两次是9923,但结果是9932,所以遇到后面连续的一样的时候,我们要dfs尝试所有可能。。。。
#include
using namespace std;

int n,ans1,ans2;
char s[11];
int a[11],b[11];

int get1(int x)
{
    int xx=999;
    if(x==1){
        for(int i=x+1;i<=n;i++){
            if(a[i])xx=min(a[i],xx);
        }
    } else {
        for(int i=x+1;i<=n;i++){
            xx=min(a[i],xx);
        }
    }return xx;
}

void dfs1(int x,int step)
{
    if(step==0||x==n){
        int res=0;
		for(int i=1;i<=n;i++){
            res=res*10+a[i];
        }
        ans1=min(ans1,res);
    	return;
	}
    int xx=get1(x);
    if(a[x]>xx){
        for(int i=x+1;i<=n;i++){
            if(a[i]==xx){
                swap(a[i],a[x]);
                dfs1(x+1,step-1);
                swap(a[i],a[x]);
            }
        }
    } else dfs1(x+1,step);
}

int get2(int x)
{
    int xx=-1;
    if(x==1){
        for(int i=x+1;i<=n;i++){
            if(a[i])xx=max(a[i],xx);
        }
    } else {
        for(int i=x+1;i<=n;i++){
            xx=max(a[i],xx);
        }
    }return xx;
}

void dfs2(int x,int step)
{
    if(step==0||x==n){
        int res=0;
		for(int i=1;i<=n;i++){
            res=res*10+a[i];
        }
        ans2=max(ans2,res);
    	return;
	}
    int xx=get2(x);
    if(a[x]<xx){
        for(int i=x+1;i<=n;i++){
            if(a[i]==xx){
                swap(a[i],a[x]);
                dfs2(x+1,step-1);
                swap(a[i],a[x]);
            }
        }
    } else dfs2(x+1,step);
}

int main()
{
    ios::sync_with_stdio(false);
   // freopen("in.txt","r+",stdin);
    int _;cin>>_;
    while(_--){
        int k;
        cin>>(s+1)>>k;
        n=strlen(s+1);
        for(int i=1;i<=n;i++)b[i]=a[i]=s[i]-'0';
        if(k>=n-1){
            sort(a+1,a+1+n);
            if(a[1]==0){
            	for(int i=2;i<=n;i++){
            		if(a[i]){
            			swap(a[i],a[1]);
            			break;
					}
				}
			}
			sort(b+1,b+1+n,[](int c1,int c2){return c1>c2;});
            for(int i=1;i<=n;i++)cout<<a[i];
            cout<<" ";
            for(int i=1;i<=n;i++)cout<<b[i];
            cout<<endl;
            continue;
        }
        ans1=1e9+10;
        ans2=-1;
        dfs1(1,k);
        dfs2(1,k);
        cout<<ans1<<" "<<ans2<<endl;
    }
    return 0;
}

你可能感兴趣的:(HDU)