D - Permute Digits
You are given two positive integer numbers a and b. Permute (change order) of the digits of a to construct maximal number not exceeding b. No number in input and/or output can start with the digit 0.
It is allowed to leave a as it is.
Input
The first line contains integer a (1 ≤ a ≤ 1018). The second line contains integer b (1 ≤ b ≤ 1018). Numbers don’t have leading zeroes. It is guaranteed that answer exists.
Output
Print the maximum possible number that is a permutation of digits of a and is not greater than b. The answer can’t have any leading zeroes. It is guaranteed that the answer exists.
The number in the output should have exactly the same length as number a. It should be a permutation of digits of a.
Example
Input
123
222
Output
213
Input
3921
10000
Output
9321
Input
4940
5000
Output
4940
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int k = 0;
int main(){
char a[20],b[20];
int ans[20],cnt[10],flag,flag1;
memset(cnt,0,sizeof(cnt));
flag = -2;
flag1 = 0;
cin>>a>>b;
for(int i = 0;i < strlen(a);i++)
cnt[a[i]-'0']++;
///位数比b小,直接逆序输出
if(strlen(a)<strlen(b)){
for(int i = 9;i>=0;i--){
while(cnt[i]-- != 0) ans[k++] = i;
}
}
///位数相等的时候
else{
while(k<strlen(a)){
///判断是否需要回溯
if(flag == 1){
k--;
cnt[ans[k]]++;
for(int i = b[k]-'0'-1;i>=0;i--){
if(cnt[i]!=0){
ans[k] = i;
cnt[i]--;
flag = -1;
break;
}
}
///如果回溯,此时一定比b该位的数小,后面直接逆序输出
if(flag == -1) break;
if(flag == 1) continue;
}
///如果i位和b该位相等继续循环
if(cnt[b[k]-'0']!=0){
cnt[b[k]-'0']--;
ans[k] = b[k]-'0';
}
///如果i位比b该位小,打破循环,后面逆序输出
else{
flag1 = 0;
for(int i = (b[k]-'0')-1;i>=0;i--){
if(cnt[i]!=0){
ans[k] = i;
cnt[i]--;
flag1 = flag = -1;
break;
}
}
if(flag1 != -1) flag = 1;
}
if(flag == -1) break;
if(flag==1) continue;
k++;
}
}
///中途跳出来循环 剩下的逆序输出
if(flag == -1){
for(int i = 9;i >= 0;i--)
while(cnt[i]!=0){
ans[++k] = i;
cnt[i]--;
}
for(int i = 0;i < strlen(a);i++)
cout<<ans[i];
cout<<endl;
}
///中途为打破循环 等于b或者位数比b小
else{
for(int i = 0;i < strlen(a);i++)
cout<<ans[i];
cout<<endl;
}
return 0;
}
代码方法:计数a中0-9出现个数,然后从第一位开始找,如果有和b改为相等的数,继续循环,如果没有,找比b该位小的数(如果没有比b该位小的数,回溯上一位找比b小的数)。注意其中的flag的值变化。
修改过程中卡死的好久的一个特例:1230 1300