题解:CF915C Permute Digits
题意
给出两个正整数 \(a,b\)。在十进制下重排 \(a\),构造一个不超过 \(b\) 的最大数,不能有前导零。允许不去重排 \(a\)。
分析
因为位数小于等于 19,考虑搜索。
开个桶维护 \(a\) 中每个数码的个数,按位搜索即可。
每一位贪心地从大到小枚举,显然这是最优的。
最劣复杂度是 \(O(a)\),但是因为最多有一个位置无法贪心选择,实际复杂度为 \(O(\log a)\)。
Code
#include<bits/stdc++.h>
using namespace std;
int cnt[10];
string a, b, det;
void dfs(int p, bool lead, bool up)
{
if(!~p) cout<<det, exit(0);
int mx=up?b[p]-'0':9;
int mn=lead;
for(int i=mx;i>=mn;i--)
{
if(!cnt[i]) continue;
cnt[i]--;
det+=i+'0';
dfs(p-1, 0, up&&i==b[p]-'0');
cnt[i]++;
det.pop_back();
}
}
int main()
{
cin>>a>>b;
reverse(b.begin(), b.end());
if(a.size()<b.size())
{
sort(a.begin(), a.end(), greater<char>());
return cout<<a, 0;
}
for(auto c:a) cnt[c-'0']++;
dfs(a.size()-1, 1, 1);
}

浙公网安备 33010602011771号