cf915 C. Permute Digits(搜索)
题意:
给定两个整数 b 和 a ,重排 b ,使得 b 尽量大但是不大于 a。
范围 1e18,两数位数不一定相等。保证答案存在。
思路:
开个桶记录 b[] 中数字出现的次数,cnt[i] 表示当前剩下几个 i 可以使用。
dfs(int u, bool same) 表示现在要填第 u 位,前面的位是不是完全和 a[] 一样。每次从9到0找数填,如果 same = true 则还需要求准备填的数不大于 a[u] 。
#include <bits/stdc++.h>
using namespace std;
int a[21], b[21], ans[21], na, nb;
int cnt[11]; //b[]的桶
bool dfs(int u, bool same)
{
if(u > nb) return 1;
if(same)
{
for(int i = 9; i >= 0; i--)
if(cnt[i] && i <= a[u])
{
--cnt[i], ans[u] = i;
if(i == a[u])
{
if(dfs(u+1, 1)) return 1;
else ++cnt[i];
}
else
{
if(dfs(u+1, 0)) return 1;
else ++cnt[i];
}
}
return 0;
}
else
{
for(int i = 9; i >= 0; i--)
if(cnt[i])
{
--cnt[i], ans[u] = i;
if(dfs(u+1, 0)) return 1;
else ++cnt[i];
}
return 0;
}
}
string str;
signed main()
{ //读进字符串再转成数组
cin >> str; nb = str.size();
for(int i = 0; i < nb; i++) b[i+1] = str[i]-'0', cnt[b[i+1]]++;
cin >> str; na = str.size();
for(int i = 0; i < na; i++) a[i+1] = str[i]-'0';
if(nb < na)
{
sort(b + 1, b + 1 + nb, greater<int>());
for(int i = 1; i <= nb; i++) printf("%d", b[i]);
}
else
{
if(nb > na) while(nb > na) --cnt[0], --nb; //去掉一些0
dfs(1, 1);
for(int i = 1; i <= nb; i++) printf("%d", ans[i]);
}
return 0;
}

浙公网安备 33010602011771号