题意:
给出两个正整数a,b。在十进制下重排a,构造一个不超过b的最大数,不能有前导零。允许不去重排a。
输入格式:
第一行一个数a(1<=a<=1018),第二行一个数b(1<=b<=1018)
数没有前导零,数据保证有解。
输出格式:
输出一个数,表示a重排后不超过b的最大数,不应该有前导零。
输出的数的长度应该与a相等,它应该是a的一个排列。
思路:
以字符串的形式输入,先将a字符串从小到大排序,然后dfs搜索来找到不超过b的最大数,需要经过剪枝优化来降低复杂度
代码:
#include<iostream>
#include<algorithm>
#include<queue>
#include<set>
#include<unordered_map>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<map>
#include<cmath>
#include<bitset>
#define ll long long
#define SE_IT set<node>::iterator
#define inf 0x3f3f3f3f
#define bug(a) cout<<"* "<<a<<endl;
#define bugg(a,b) cout<<"* "<<a<<" "<<b<<endl;
#define buggg(a,b,c) cout<<"* "<<a<<" "<<b<<" "<<c<<endl;
using namespace std;
typedef pair<int,int> pii;
const int N=1e5+10;
const double esp=1e-5;
const ll mod=1e9+7;
string s1,s2,ans;
bool vis[N];
bool flag;
void dfs(string x,int y,bool flag){
//bug(x)
if(x.size()==s1.size()){
ans=x;
return ;
}
for(int i=0;i<s1.size();i++){
if(!vis[i]){
if(!flag&&s1[i]>s2[y]) continue;
if(!flag&&s1[i]==s2[y]){
string st="",st2;
st2=s2.substr(y,s2.size()-y);
for(int i=0;i<s1.size();i++)
if(!vis[i])
st+=s1[i];
sort(st.begin(),st.end());
if(st>st2) return ;
if(st==st2){
ans=x+st;
return ;
}
}
if(s1[i]<s2[y])
flag=1;
vis[i]=1;
dfs(x+s1[i],y+1,flag);
vis[i]=0;
if(ans.size()>0)
return ;
}
}
}
int main()
{
cin>>s1>>s2;
sort(s1.begin(),s1.end(),greater<char>());
if(s1.size()<s2.size()){
ans=s1;
}
else
dfs("",0,0);
cout<<ans<<endl;
return 0;
}
/*
2000000000001
2000000000000
*/