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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值