HDU 6351 Beautiful Now(DFS)
Beautiful Now
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 750 Accepted Submission(s): 259
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
題意:給你一個數字,你可以交換最多k次,每次交換任意位置的兩個數字。求最小和最大得到的數是哪兩個數。
思路:第一發貪心WA了之後就意識到情況不對。明智的選擇了爆搜一發過。不過寫的比較麻煩,用了兩個dfs分別求了最大最小。關鍵是前面的數字與後面的數字交換的時候,後邊可交換的數字有多個相同的,直接爆搜交換哪一個。然後判斷最大最小即可。。。由於加了許多剪枝,0ms通過。。。
程式碼:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=15;
int n,m,k;
int sum[maxn];
int c[maxn];
int ct,cnt,tmp,flag,f,l;
string s,ss;
char s1[maxn];
string ans,anss;
bool vis[maxn];
bool jud(int len)
{
for(int i=0;i<len;i++)
if(ans[i]>s[i])return 0;
else if(ans[i]<s[i]) return 1;
return 1;
}
bool judd(int len)
{
for(int i=0;i<len;i++)
if(anss[i]<ss[i])return 0;
else if(anss[i]>ss[i]) return 1;
return 1;
}
void dfs(int pos,int cnt)
{
if(cnt==k||pos==l)
{
//cout<<s<<" * "<<(flag)<<endl;
if(flag||jud(l)) {
flag=0;
ans=s;
// cout<<flag<<" "<<s<<endl;
return;}
}
if(cnt>=k||pos>=l)return;
if(!flag&&!jud(pos)) return;
int i=pos;
for(int j=pos+1;j<l;j++)
if(s[i]<s[j]){
i=j;
}
if(i==pos) dfs(pos+1,cnt);
else {
for(int j=pos+1;j<l;j++)
if(s[j]==s[i])
{
swap(s[pos],s[j]);
dfs(pos+1,cnt+1);
swap(s[pos],s[j]);
}
}
}
void dfss(int pos,int cnt)
{
if(cnt==k||pos==l)
{
// cout<<ss<<" ***"<<endl;
if(flag||judd(l)) {flag=0;anss=ss;return;}
}
if(cnt>=k||pos>=l)return;
if(!flag&&!judd(pos)) return;
int i=pos;
for(int j=pos+1;j<l;j++)
if(ss[i]>ss[j]&&(!(pos==0&&ss[j]=='0'))){//注意不能有前導0
i=j;
}
if(i==pos) dfss(pos+1,cnt);
else {
for(int j=pos+1;j<l;j++)
if(ss[j]==ss[i])
{
swap(ss[pos],ss[j]);
dfss(pos+1,cnt+1);
swap(ss[pos],ss[j]);
}
}
}
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%s",s1);
scanf("%d",&k);
l=strlen(s1);
s=(string)s1;
ss=(string)s1;
flag=1;
dfs(0,0);
flag=1;
dfss(0,0);
printf("%s %s\n",anss.c_str(),ans.c_str());
// if(flag) puts("Yes"); else puts("No");
}
return 0;
}