HDU 6351 Beautiful Now(暴力/搜索)

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

扫描二维码关注公众号,回复: 2843566 查看本文章

998244353 1

998244353 2

998244353 3

Sample Output

12 21

123 321

298944353 998544323

238944359 998544332

233944859 998544332

题目大意:给出一个数字,和最多能操作的次数。操作:数字2个位上的数互相交换。要求输出在规定操作次数下最大数值和最小数值。

思路:这题不能用贪心,不能用贪心,不能用贪心。反正我怎么贪都过不了,没有考虑暴力,虽然题目给的时间是2500ms,,,事实证明还是暴力大法好啊,该题有2种做法,第一种是用全排列暴力求解,时间大概在2100ms左右,算是卡过,第二种是用搜索来爆搜,减枝后时间能达到0ms或15ms(MD)

全排列做法:用STL中的全排列函数,对原数组进行标记,根据标记来找每一次排列结果的交换次数(不用考虑相同的数应该交换哪一位,因为最后会去最大值和最小值,,,,,真*暴力)

代码如下:(我也要向这种码风靠拢)

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<cmath>
#include<queue>
#include<stdlib.h>
#include<ext/rope>
#define per(i,a,b) for(int i=a;i<=b;++i)
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
using namespace std;
using namespace __gnu_cxx;
typedef long long LL;
int k,len;
int p[15];
int num[15];
bool vis[15];
int check()
{
    memset(vis,0,sizeof(vis));
    int c=0;
    per(i,0,len-1)
	{
        if(vis[i]!=0) continue;
        int tmp=0;
        while(vis[i]==0)
		{
            tmp++;
            vis[i]=1;
            i=p[i];
        }//根据全排列错位情况得出换位次数。(无法判定相同数字不同编号的换位情况,但取最值排除了这个问题) 
        c+=tmp-1;//换位次数累加 
        if(c>k) return 0;
    }
    return c;
}
char s[15];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
	{
        memset(s,0,sizeof(s));
        scanf("%s %d",s,&k);
        len=strlen(s);
        LL n=0;
        per(i,0,len-1)
		{
		    num[i]=s[i]-'0';
			p[i]=i;//存顺序 
			n=n*10+num[i];
		}    
        LL ans1=n,ans2=n;
        do
		{
            if(num[p[0]]!=0&&check()!=0)
			{
                LL z=0;
                per(i,0,len-1)
				{
                    z*=10;
                    z+=num[p[i]];
                } 
                ans1=min(z,ans1); 
                ans2=max(z,ans2);
            } 
        }while(next_permutation(p,p+len)); //枚举全排列 
        printf("%lld %lld\n",ans1,ans2);
    }
    return 0;
}//暴力大法好啊,真的好啊。 

爆搜做法: (暂未成功,会补上的,逃~~)

猜你喜欢

转载自blog.csdn.net/PleasantlY1/article/details/81476893
今日推荐