对于比较小的数,考虑直接跑。例如 $N \leq 10000$。
对于其余的,需要保证找到的数 $x$ 满足要求,并在 $[N,2N)$ 之间,且 $x+1$ 满足要求。
考虑到题目条件的性质,若 $x$ 各位之和为 $8$ 且最后三个数是 $0$,且这个数合法,那么 $x+1$ 一定是合法的。
因为 $x+1$ 各位之和为 $9$,所以一定是 $9$ 的倍数。
那么就是如何构造的问题了,发现最高位对这个数的限制最大,设 $N$ 的最高位为 $t$,长度为 $n$。
- $6 \leq t \leq 9$:构造 $107$ 接上 $n-2$ 个 $0$。
- $2 \leq t \leq 5$:构造 $t+1$ 接 $8-(t+1)$ 接 $n-2$ 个 $0$。
- $t=1$:
- 设第二位为 $y$。
- 若 $4 \leq y \leq 19$,同构造方法 2。
- 若 $1 \leq y \leq 3$:构造 $206$ 接 $n-3$ 个 $0$。
- 若 $y=0$:构造 $17$ 接 $n-2$ 个 $0$。
值得一提的是 AT 的数据非常水,$t=1$ 写错了还给过了。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 15;
int n;
char a[N];
bool check(int x) {
int cnt = 0, y = x;
while (y) cnt += y % 10, y /= 10;
return (x % cnt == 0);
}
void bf() {
int x = 0;
for (int i = 1; i <= n; i++) x = x * 10 + a[i] - '0';
for (int i = x; i < 2 * x; i++)
if (check(i) && check(i + 1)) return printf("%d\n", i), void();
puts("-1");
}
void solve() {
int x = a[1] - '0', y = a[2] - '0';
if (x >= 6) {
printf("107");
for (int i = 1; i <= n - 2; i++) putchar('0');
} else if (x >= 2 || (x == 1 && y >= 4) ) {
printf("%d%d", x + 1, 8 - (x + 1));
for (int i = 1; i <= n - 2; i++) putchar('0');
} else if (y >= 1) {
printf("206");
for (int i = 1; i <= n - 3; i++) putchar('0');
} else {
printf("17");
for (int i = 1; i <= n - 2; i++) putchar('0');
}
}
int main() {
scanf("%s", a + 1), n = strlen(a + 1);
if (n <= 5) return bf(), 0;
solve();
return 0;
}