Permute Digits

本文介绍了一个名为D-PermuteDigits的算法问题,该问题要求通过改变一个给定正整数a的数字顺序来构造一个不超过另一个给定正整数b的最大可能数值。文章详细解释了算法的具体实现过程,包括输入输出格式、示例和核心代码逻辑。

D - 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.

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

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int k = 0;
int main(){
    char a[20],b[20];
    int ans[20],cnt[10],flag,flag1;
    memset(cnt,0,sizeof(cnt));
    flag = -2;
    flag1 = 0;
    cin>>a>>b;
    for(int i = 0;i < strlen(a);i++)
        cnt[a[i]-'0']++;
    ///位数比b小,直接逆序输出 
    if(strlen(a)<strlen(b)){
        for(int i = 9;i>=0;i--){
            while(cnt[i]-- != 0) ans[k++] = i;
        }
    }
    ///位数相等的时候 
    else{
        while(k<strlen(a)){
            ///判断是否需要回溯 
            if(flag == 1){
                k--;
                cnt[ans[k]]++;
                for(int i = b[k]-'0'-1;i>=0;i--){
                    if(cnt[i]!=0){
                        ans[k] = i;
                        cnt[i]--;
                        flag = -1;
                        break;
                    }
                }
                ///如果回溯,此时一定比b该位的数小,后面直接逆序输出 
                if(flag == -1) break;
                if(flag == 1) continue;         
            }
            ///如果i位和b该位相等继续循环 
            if(cnt[b[k]-'0']!=0){
                cnt[b[k]-'0']--;
                ans[k] = b[k]-'0';
            }
            ///如果i位比b该位小,打破循环,后面逆序输出 
            else{
                flag1 = 0;
                for(int i = (b[k]-'0')-1;i>=0;i--){
                    if(cnt[i]!=0){
                        ans[k] = i;
                        cnt[i]--;
                        flag1 = flag = -1;
                        break;
                    }
                }
                if(flag1 != -1) flag = 1;
            }
            if(flag == -1) break;
            if(flag==1) continue;
            k++;
        }

    }
    ///中途跳出来循环 剩下的逆序输出 
    if(flag == -1){
        for(int i = 9;i >= 0;i--)
            while(cnt[i]!=0){
                ans[++k] = i;
                cnt[i]--;   
            }
        for(int i = 0;i < strlen(a);i++)
            cout<<ans[i];
            cout<<endl; 
    }
    ///中途为打破循环 等于b或者位数比b小 
    else{
        for(int i = 0;i < strlen(a);i++)
            cout<<ans[i];
            cout<<endl; 
    }
    return 0;
}

代码方法:计数a中0-9出现个数,然后从第一位开始找,如果有和b改为相等的数,继续循环,如果没有,找比b该位小的数(如果没有比b该位小的数,回溯上一位找比b小的数)。注意其中的flag的值变化。
修改过程中卡死的好久的一个特例:1230 1300

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdbool.h> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <limits.h> //宏定义与类型别名 #define EPS 1e-9 #define MOD 100000000 #define in int #define ll long long #define fl float #define db double #define ch char #define vd void #define pr printf #define sc scanf #define pr_in(x) pr("%d", x) #define pr_ll(x) pr("%lld", x) #define pr_st(x) pr("%s", x) #define pr_inn(x) pr("%d\n", x) #define pr_lln(x) pr("%lld\n", x) #define pr_stn(x) pr("%s\n", x) #define feq(a, b) (fabs((a) - (b)) < EPS) //函数声明:库函数模拟 vd* memchr_exp(const vd* str, in c, size_t n); //函数声明:输入输出辅助 in fast_read(); vd scan_arr(in arr[], in n); vd print_arr(in arr[], in n); //函数声明:数学计算 ll factorial1(in n); ll factorial2(in n); ll fibonacci1(in n); ll fibonacci2(in n); ll fibonacci2_memo(in n); ll permute(in n, in k); ll combine(in n, in k); ll pow_mod(ll base, ll exp); in gcd(in a, in b); in lcm(in a, in b); in is_prime(in n); in digit_change(in n, in digit2); in bin_to_dec(in bin); in turn_digits(in n); //函数声明:字符串处理 in is_palindrome(const ch* s); in contains_digit1(in n, in p); in contains_digit2(const ch* num_str, in p); vd string_frequency(const ch* str); //函数声明:数组操作 vd extract_digits(in num, in digits[]); //函数声明:排序与搜索 vd swap(in* a, in* b); vd bubble_sort(in* arr, size_t n); vd quick_sort(in arr[], in l, in r); vd permute(in arr[], in start, in end); vd reverse_arr(in arr[], in n); in sum_arr(in arr[], in n); in max_index(in arr[], in n); in binary_search(in arr[], in n, in x); //函数声明:几何计算 db distance_2d(db x1, db y1, db x2, db y2); ll triange_area_2(ll x1, ll y1, ll x2, ll y2, ll x3, ll y3); ll n_triangle_area_2(in n, ll x[], ll y[]); //函数声明:时间日期 in is_leap(in year); in get_days_of_month(in year, in month); in get_week_day(in year, in month, in day); int main() { } //函数实现:库函数模拟 vd* memchr_exp(const vd* str, in c, size_t n) { const unsigned ch* ptr = (const unsigned ch*)str; unsigned ch uc = (unsigned ch)c; for (size_t i = 0; i < n; i++) { if (ptr[i] == uc) { return (vd*)(ptr + i); } } return NULL; } //in main() //{ // ch str[] = "Hello, world!"; // ch* result = (ch*)memchr_exp(str, 'w', sizeof(str)); // if (result != NULL) // { // pr("字符'w'首次出现在索引:%d\n", result - str); // pr("子字符串:%s\n", result); // } // else // { // pr("未找到字符'w'\n"); // } // result = (ch*)memchr_exp(str, 'x', sizeof(str)); // if (result == NULL) // { // pr("字符'x'未找到\n"); // } // return 0; //} //函数实现:输入输出辅助 //要求快速输入 in fast_read() { in x = 0, f = 1; ch c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -f; c = getchar(); } while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); } return x * f; } //要求数组输入 vd scan_arr(in arr[], in n) { for (in i = 0; i < n; i++) { sc("%d", &arr[i]); } } //要求数组输出 vd print_arr(in arr[], in n) { for (in i = 0; i < n; i++) { pr("%d ", arr[i], " \n"[i == n - 1]); } } //函数实现:数学计算 //求某个数的阶乘(非递归) ll factorial1(in n) { if (n < 0) return -1; if (n > 20) return -1; ll result = 1; for (in i = 2; i <= n; i++) { result *= i; } return result; } //求某个数的阶乘(递归) ll factorial2(in n) { if (n <= 1) { return 1; } return n * factorial2(n - 1); } //求斐波那契数列第某个数(非递归) ll fibonacci1(in n) { if (n == 0) return 0; if (n == 1) return 1; ll prev = 0; ll curr = 1; ll next; for (in i = 2; i <= n; i++) { next = prev + curr; prev = curr; curr = next; } return curr; } //求斐波那契数列第某个数(递归) ll fibonacci2(in n) { if (n == 1 || n == 2) { return 1; } return fibonacci2(n - 1) + fibonacci2(n - 2); } //求斐波那契数列第某个数(递归+优化) ll memo[1000] = { 0 }; ll fibonacci2_memo(in n) { if (n == 1 || n == 2) { return 1; } if (memo[n] != 0) { return memo[n]; } memo[n] = fibonacci2_memo(n - 1) + fibonacci2_memo(n - 2); return memo[n]; } //求排列数P(n数,排k) ll permute(in n, in k) { if (k < 0 || n < 0 || k > n) { return -1; } ll result = 1; for (in i = n - k + 1; i <= n; i++) { result *= i; } return result; } //求组合数C(n数,组k) ll combine(in n, in k) { if (k < 0 || n < 0 || k > n) { return -1; } if (k > n - k) { k = n - k; } ll result = 1; for (in i = 0; i < k; i++) { result = result * (n - i) / (i + 1); } return result; } //求快速幂(模幂运算) ll pow_mod(ll base, ll exp) { ll result = 1; while (exp > 0) { if (exp & 1) { result = (result * base) % MOD; } base = (base * base) % MOD; exp >>= 1; } return result; } //求两个数的最大公因数 in gcd(in a, in b) { if (a < 0) a = -a; if (b < 0) b = -b; while (b != 0) { in temp = b; b = a % b; a = temp; } return a; } //求两个数的最小公倍数 in lcm(in a, in b) { return a / gcd(a, b) * b; } //求某个数是否为素数 in is_prime(in n) { if (n <= 1) { return 0; } else if (n <= 3) { return 1; } else if (n % 2 == 0 || n % 3 == 0) { return 0; } for (in i = 5; i * i <= n; i += 6) { if (n % i == 0 || n % (i + 2) == 0) { return 0; } } return 1; } //求10进制转<10进制(待拓展) in digit_change(in n, in digit2) { in rem = n; in mod[100]; in i = 0; while (rem > 0) { mod[i] = rem % digit2; rem = rem / digit2; i++; } in result = 0; in ten = 1; for (in j = 0; j < i; j++) { result += mod[j] * ten; ten = 10 * ten; } return result; } //求2进制数转10进制数 in bin_to_dec(in bin) { if (bin == 0) { return 0; } if (bin < 0) { return -1; } in decimal = 0; in base = 1; while (bin > 0) { in digit = bin % 10; if (digit != 0 && digit != 1) { return -1; } decimal += digit * base; base *= 2; bin /= 10; } return decimal; } //求某个数字的反向输出 in turn_digits(in n) { in digits[10] = { 0 }; in i = 0; in num = n; while (num > 0) { digits[i++] = num % 10; num /= 10; } in ans = 0; for (in j = 0; j < i; j++) { ans = ans * 10 + digits[j]; } return ans; } //函数实现:字符串处理 //求某个数(字符串形式)是否为回文 in is_palindrome(const ch* s) { if (s == NULL) { return 0; } in left = 0; in right = strlen(s) - 1; while (left < right) { if (tolower(s[left]) != tolower(s[right])) { return 0; } left++; right--; } return 1; } //求某数是否含某数字(一般数) in contains_digit1(in n, in p) { ch str[50]; ch target = '0' + p; sprintf(str, "%d", n); for (in i = 0; str[i] != '\0'; i++) { if (str[i] == target) { return 1; } } return 0; } //求某数是否含某数字(超大数,%s输入num_str) in contains_digit2(const ch* num_str, in p) { ch target = '0' + p; for (in i = 0; num_str[i] != '\0'; i++) { if (num_str[i] < '0' || num_str[i] > '9') { continue; } if (num_str[i] == target) { return 1; } } return 0; } //求给定字符串出现频次 vd string_frequency(const ch* str) { in freq[128] = { 0 }; for (in i = 0; str[i] != '\0'; i++) { unsigned ch c = str[i]; if (c == ' ' || isprint(c)) { freq[c]++; } } int count = 0; for (in i = 0; i < 128; i++) { if (freq[i] > 0) { count++; if (i == ' ') { pr("blank: %d\n", freq[i]); } else { pr("'%c': %d\n", i, freq[i]); } } } } //函数实现:数组操作 //求某十进制数的各位数 vd extract_digits(in num, in digits[]) { if (num == 0) { digits[0] = 0; digits[1] = -1; return; } in i = 0; while (num > 0) { digits[i++] = num % 10; num /= 10; } } //函数实现:排序与搜索 //要求两个整数交换 vd swap(in* a, in* b) { in temp = *a; *a = *b; *b = temp; } //要求升序排列(冒泡排序) vd bubble_sort(in* arr, size_t n) { if (arr == NULL || n < 2) { return; } for (size_t i = 0; i < n - 1; i++) { in swapped = 0; for (size_t j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { in temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; swapped = 1; } } if (!swapped) { break; } } } //要求升序排列(快速排序1到r) vd quick_sort(in arr[], in l, in r) { if (l >= r) { return; } in i = l, j = r; in pivot = arr[(l + r) / 2]; while (i <= j) { while (arr[i] < pivot) i++; while (arr[j] > pivot) j--; if (i <= j) { swap(&arr[i], &arr[j]); i++; j--; } } quick_sort(arr, l, j); quick_sort(arr, i, r); } //要求全排数组(start到end) vd permute_arr(in arr[], in start, in end) { if (start == end) { for (in i = 0; i <= end; i++) { pr("%d ", arr[i]); } pr("\n"); } else { for (in i = start; i <= end; i++) { swap(&arr[start], &arr[i]); permute(arr, start + 1, end); swap(&arr[start], &arr[i]); } } } //要求翻转数组 vd reverse_arr(in arr[], in n) { for (in i = 0; i < n / 2; i++) { in t = arr[i]; arr[i] = arr[n - 1 - i]; arr[n - 1 - i] = t; } } //求数组某元素的位置(升序,n元,二分找x) in binary_search(in arr[], in n, in x) { in left = 0, right = n - 1; while (left <= right) { in mid = (left + right) / 2; if (arr[mid] == x) { return mid; } else if (arr[mid] < x) { left = mid + 1; } else right = mid - 1; } return -1; } //求数组各元素的和 in sum_arr(in arr[], in n) { in s = 0; for (in i = 0; i < n; i++) { s += arr[i]; } return s; } //求数组最大元素下标 in max_index(in arr[], in n) { in idx = 0; for (in i = 1; i < n; i++) { if (arr[i] > arr[idx]) { idx = i; } } return idx; } //函数实现:几何计算 //求平面上两点的距离 db distance_2d(db x1, db y1, db x2, db y2) { db dx = x2 - x1; db dy = y2 - y1; return sqrt(dx * dx + dy * dy); } //求三角形的面积(2倍) ll triange_area_2(ll x1, ll y1, ll x2, ll y2, ll x3, ll y3) { ll area_2 = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1); return area_2 < 0 ? -area_2 : area_2; } //求凸多边形面积(2倍) ll n_triangle_area_2(in n, ll x[], ll y[]) { ll area_2 = 0; for (in i = 0; i < n; i++) { in j = (i + 1) % n; area_2 += x[i] * y[j] - x[j] * y[i]; } return area_2 > 0 ? area_2 : -area_2; } //函数实现:时间日期 //求某年是否为闰年 in is_leap(in year) { return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0); } //求某年某月的天数 in get_days_of_month(in year, in month) { in days = 0; switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: days = 31; break; case 4: case 6: case 9: case 11: days = 30; break; case 2: days = is_leap(year) ? 29 : 28; break; } return days; } //求某年某月某日为星期几 in get_week_day(in year, in month, in day) { in century, weekday; if (month < 3) { year--; month += 12; } century = year / 100; year %= 100; weekday = (year + year / 4 + century / 4 - 2 * century + (26 * (month + 1)) / 10 + day - 1) % 7; if (weekday < 0) { weekday += 7; } return weekday; }帮我再函数声明部分每个对应声明前添加对应的功能(把函数实现处我的注释复制过去即可,其他不要改动)
最新发布
10-29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值