Codeforces 915C Permute Digits

龍威昊發表於2019-05-09

Permute Digits

time limit per test:1 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output

Problem Description

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 ≤ 10^18). The second line contains integer b (1 ≤ b ≤ 10^18). 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.

Sample Input

123
222
3921
10000
4940
5000

Sample Output

213
9321
4940


http://codeforces.com/contest…


Accepted Code

// Author : Weihao Long
// Created : 2018/01/15

#include "stdio.h"
#include "string.h"

#define ll long long

int main() {
    ll a, b;
    while (scanf("%lld%lld", &a, &b) != EOF) {
        char aa[20], bb[20];
        sprintf(aa, "%lld", a);
        sprintf(bb, "%lld", b);
        int lena = strlen(aa);
        int lenb = strlen(bb);
        if (lenb > lena) {
            for (int i = 1; i < lena; i++)
                for (int k = 0; k < lena - i; k++)
                    if (aa[k] < aa[k + 1]) {
                        char tmp = aa[k];
                        aa[k] = aa[k + 1];
                        aa[k + 1] = tmp;
                    }
        }
        else {
            int c[10] = { 0 };
            for (int i = 0; i < lena; i++)
                c[aa[i] - `0`]++;
            ll ans = 0;
            for (int i = 0; i < lenb; i++) {
                int index = 0, flag = 0;
                for (int k = 9; k >= 0; k--) {
                    if (c[k] && k < bb[i] - `0`) {
                        ans = ans * 10 + k;
                        c[k]--;
                        index = 1;
                        flag = 1;
                        break;
                    }
                    else if (c[k] && k == bb[i] - `0`) {
                        ans = ans * 10 + k;
                        c[k]--;
                        index = 1;
                        break;
                    }
                }
                while (!index) {
                    i--;
                    int last = ans % 10;
                    c[last]++;
                    ans /= 10;
                    for (int k = last - 1; k >= 0; k--)
                        if (c[k]) {
                            ans = ans * 10 + k;
                            c[k]--;
                            index = 1;
                            flag = 1;
                            break;
                        }
                }
                if (flag || i == lenb - 1) {
                    for (;;) {
                        int k;
                        for (k = 9; k >= 0; k--) {
                            if (c[k]) {
                                ans = ans * 10 + k;
                                c[k]--;
                                break;
                            }
                        }
                        if (k == -1)
                            break;
                    }
                    sprintf(aa, "%lld", ans);
                    break;
                }
            }
        }
        puts(aa);
    }
    return 0;
}

Notes

題意:
輸入兩個數 a 和 b,你可以對 a 調整數字的順序,要求調整後的 a 儘可能大,但同時要小於 b。

演算法:
第一步:將 a 和 b 輸出到字串 aa 和 bb 中。
第二步:如果 a 的位數小於 b,那麼只須將 a 的數字降序排列即可。
第三步:否則就是 a 的位數等於 b 的位數的情況。先統計 a 中各數字的個數。
第四步:以 b 為基準,從頭掃到尾,從 a 中挑選合適的數字與之匹配。
第五步:若沒有可匹配的,則回退,換小的數字。(重複執行此步直到找到可匹配的數字為止)

相關文章