CodeForces 915C Permute Digits
题目大意:
给两个数a,b,对 a 的各个位置的数字重新排列,找出比 b 小的最大排列。题目保证输入有结果。
解题思路:
- 用头文件 sstream 的 stringstream 得到 a,b 的字符形式和数字形式
- 由a ,b的字符长度分情况讨论
- a.size() < b.size() ,将 a 的最大排列输出。
- a.size() == b.size() ,从第一个数字开始判断,尽可能使新排列相应位置数字与 b 相同, 但不得不出现第一不同之后(即新排列在之后必然小于 b ),将剩余的数字按最大排列输出。
AC代码:
#include<cstdio>
#include<iostream>
#include<queue>
#include<string>
#include<cmath>
#include<algorithm>
#include<limits.h>
#include<sstream>
#define rep(i,l,p) for(int i=l; i<=p; i++)
#define drep(i,p,l) for(int i=p; i>=l; i--)
using namespace std;
typedef long long ll;
ll a,b;
int len;
bool flag;
string s1,s2,ans;
int numa[11];
void dfs(int x){
//cout << flag <<"dfs" << endl;
if ( flag == true ) return ;
if ( x == s2.size() ){
flag = true;
//cout << ans.size() << endl;
return;
}
else if ( flag == false){
int maxn = s2[x] - '0';
//cout << maxn << "maxn" << endl;
drep(i,maxn,0){
if ( numa[i] > 0 && (s2[x] - '0' > i) ){
numa[i]--;
flag = true;
//cout <<"x:" <<x <<"\t"<< i << endl;
//cout << "ok" << endl;
ans += char('0'+ i);
// cout << ans << endl;
return;
}else if (numa[i] > 0){
numa[i]--;
ans += char('0' + i);
dfs(x+1);
if ( flag == true) return;
ans.erase(--ans.end());
numa[i]++;
}
}
}
return ;
}
void ini(){
rep(i,0,9) numa[i] = 0;
ans = "";
}
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(cin >> s1 >> s2){
ini();
//cout << s1 << endl << s2 << endl;
stringstream s1in(s1),s2in(s2);
s1in >> a; s2in >> b;
rep(i,0,s1.size()-1){
numa[s1[i]-'0']++;
}
//cout << numa[0]<<"\t"<< numa[1]<<endl;
if ( s1.size() < s2.size() ){
drep(i,9,0){
while( numa[i] > 0 ) {
ans += char('0'+i);
numa[i]--;
}
}
while( ans.size() > 1 && *ans.begin() == '0' ) ans.erase(ans.begin());
cout << ans << endl;
}else {
flag = false;
len = s1.size();
dfs(0);
drep(i,9,0){
while( numa[i] > 0 ) {
ans += char('0'+i);
numa[i]--;
}
}
while( ans.size() > 1 && *ans.begin() == '0' ) ans.erase(ans.begin());
cout << ans << endl;
}
}
return 0;
}