Codeforces 915C 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.

Examples
Input
123
222
Output
213
Input
3921
10000
Output
9321
Input
4940
5000
Output
4940


题意: 给你一个a,一个 b 然后让你把a重新组合 比b小的最大的a,输出找到的这个a

一开始我先附上一张每种定义类型的数据范围,因为在这题,我以为会超long long 的,但是之后查了数据后发现不是long long 的问题


之前没补的一道题,今天终于AC了

解题思路:首先我WA了2发 最后用BFS暴力过的,用了贪心思想,但是没用到DP(博主太菜,没怎么练DP,过几天一天一道基础DP),因为这个数的长度不会超过18 所以我就暴力试了试.

一开始的时候,我想到的是全排列(最偷懒的做法)

不会的同学可以学一下:C++STL中全排列函数next_permutation的使用

然后有一道模板题可以练习练习:老子的全排列(2018年全国多校算法寒假训练营练习比赛(第四场))

但是超时了(当时没考虑那么多,想偷点懒)

然后我就想到了大体思路:以字符串的形式读入两个数字 先把第一个数字读入后,统计有多少个数字,从头开始遍历第2个读入数字
假设当前遍历的位置是X

那么 我就从ch2[X]-'0' ,这个数往下遍历,直到第一个存在的数字,然后加到答案里面去。如果找到的数字不等于ch2[X]-'0'的时候 你就可以从9开始遍历下去寻找。


比如样例1

213

222


结果还是WA在了第6个样例(有点和这个数据结仇,就是不让我过)

然后我思考了十几分钟后,觉得可以用深搜写,然后就写了,就AC。

不会DP啊,自己好菜。

附上AC代码

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=20;
const int inf=0x3f3f3f3f;
int num[10],top,len2;
char ch1[maxn],ch2[maxn];
long long ans;
void find(){
	memset(num,0,sizeof(num));
	int le=strlen(ch1),i;
	for(i=0;i<le;i++){
		int te=ch1[i]-'0';
		num[te]++;
	}
}
int flag1;
void dfs(long long nu,int kk,int t){
	if(flag1) return ;
	if(kk==top){
		ans=nu;
		flag1=1;
		return;
	}
	if(t==1){
		for(int i=9;i>=0;i--){
			if(num[i]){
				long long t=nu*10;
				t+=i;
				num[i]--;
				dfs(t,kk+1,1);
				num[i]++;
			}
		}
	}
	else{
		int m=ch2[kk]-'0',j;
		for(j=m;j>=0;j--){
			if(num[j]){
				long long t=nu*10;
				t+=j;
				num[j]--;
				if(j!=m)
					dfs(t,kk+1,1);
				else
					dfs(t,kk+1,0);
				num[j]++;
			}
		}	
	}
	return ;
}
int main(){
	int i,j;
	scanf("%s%s",ch1,ch2);
	int len1=strlen(ch1);
	len2=strlen(ch2);
	top=len1;
	find();
	ans=0;
	if(len1<len2){
		for(i=9;i>=0;i--){
			if(num[i]){
				while(num[i]){
					ans*=10;
					ans+=i;
					num[i]--;
				}
			}
		}
	}
	else{
		flag1=0;
		dfs(0,0,0);
	}
	printf("%I64d\n",ans);
	return 0;
}


明天的你终会感谢现在奋斗的你!

让自己无悔大学生活


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值