4307. 数字重构

题目链接

4307. 数字重构

给定两个正整数 \(a\)\(b\),均不含前导 \(0\)

现在,请你对 \(a\) 进行重构,重新排列其各位数字顺序,得到一个不含前导 \(0\) 的新正整数。

要求新正整数在不超过 \(b\) 的前提下,尽可能大。

输出新正整数。

注意,我们允许新正整数等于 \(a\),即保持原样不变。

输入格式

第一行包含一个正整数 \(a\)

第二行包含一个正整数 \(b\)

两个输入数字均不含前导 \(0\)

输出格式

一个不含前导 \(0\) 的正整数,表示答案。

数据保证一定有解。

数据范围

\(6\) 个测试点满足 \(1≤a,b≤10^9\)
所有测试点满足 \(1≤a,b≤10^{18}\)

输入样例1:

123
222

输出样例1:

213

输入样例2:

3921
10000

输出样例2:

9321

输入样例3:

4940
5000

输出样例3:

4940

解题思路

贪心

不可能存在 \(a\) 的位数比 \(b\) 的位数还大的情况,因为 \(a\) 不能有前导零且题目保证有解,当 \(a\) 的位数小于 \(b\) 的位数时最大值即为 \(a\) 的倒序,否则对于重构 \(a\) 来说,可以从高位开始枚举 \(9\sim 0\),当前面选上的数加上这个数再加上剩余的数组成的最小数小于等于 \(b\) 时,说明这个数可以选

  • 时间复杂度:\(O(10\times loga\times loga)\)

代码

// Problem: 数字重构
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/4310/
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

string a,b;
int cnt[10];
string get_min(int x)
{
	string res;
	for(int i=0;i<=9;i++)
		if(i!=x)res+=string(cnt[i],i+'0');
		else
			res+=string(cnt[i]-1,i+'0');
	return res;
}
int main()
{
    cin>>a>>b;
    if(a.size()<b.size())
    {
    	sort(a.begin(),a.end(),greater<char>());
    	cout<<a;
    	return 0;
    }
    string res;
    for(char c:a)cnt[c-'0']++;
    for(int i=0;i<a.size();i++)
    	for(int j=9;~j;j--)
    		if(cnt[j]&&res+to_string(j)+get_min(j)<=b)
    		{
    			res+=to_string(j);
    			cnt[j]--;
    			break;
    		}
    cout<<res;
    return 0;
}
posted @ 2022-02-28 16:59  zyy2001  阅读(121)  评论(0编辑  收藏  举报