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
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;
}//暴力大法好啊,真的好啊。
爆搜做法: (暫未成功,會補上的,逃~~)