1. 程式人生 > >HDU 6351 Beautiful Now(DFS)

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;
}