Number / 好数
题目链接:jzoj 7203 / LOJ 3478
题目大意
给你一个数,要你找到第一个比大的数满足它至多 k 位于其他不同。
思路
首先看到这种鬼题不难想到每位每位看。
我们从低位往高位枚举,看比他高位的都跟那个数一样,这一位比他大,然后后面的随便选能不能有答案。
然后不难想到答案的位数不会你数的位数大因为最大的数是
99...99
99...99
99...99。
然后你就接着枚举大的数是哪个数,然后再枚举满足要求的数是哪个,然后判断一下就可以了。
然后如果判断出可以,我们要想,可能会有多出几个数。
那我们肯定是在后面随便选的高位搞
0
0
0。
然后就可以了。
代码
#include<cstdio>
#define ll long long
using namespace std;
ll x;
int k, num[11], n, y[31];
void get_num(ll now) {
num[now % 10]++;
n++;
y[n] = now % 10;
if (now > 9) get_num(now / 10);
}
int main() {
scanf("%lld %d", &x, &k);
get_num(x);
for (int i = 0; i <= 9; i++)
if (num[i] >= n - k) {
printf("%lld", x);
return 0;
}
for (int i = 1; i <= n; i++) {
num[y[i]]--;
for (int j = y[i] + 1; j <= 9; j++) {
num[j]++;
for (int l = 0; l <= 9; l++)
if (num[l] + i - 1 >= n - k) {
int mr = num[l] + i - 1 - (n - k);
int el = i - 1 - mr;
for (int o = n; o >= i + 1; o--) printf("%d", y[o]);
printf("%d", j);
for (int o = 1; o <= mr; o++) printf("0");
for (int o = 1; o <= el; o++) printf("%d", l);
return 0;
}
num[j]--;
}
}
return 0;
}