首先奇数位肯定不行,位数直接加一再进行后续判断

偶数的话使用回溯法,

结果肯定类似于110022这样有连续俩个数字的情况,不能有四个连续的数字(题目中说了恰好),所以有这几种情况,将连续两个数字看成一个块

受限选择:当前块需不小于x的对应两位数字,计算最小可能数字。

自由选择:一旦某块大于x对应部分,后续块可自由选择最小数字(跳过前驱块数字)。

回溯:若当前块无解,回溯到前一块并增大数字。 剩下的就好处理了

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String x = scanner.next();
        String result = findSmallestTwin(x);
        System.out.println(result);
    }

    public static String findSmallestTwin(String x) {
        int n = x.length();
        // 处理奇数位数情况:构造 n+1 位的最小双生数
        if (n % 2 == 1) {
            return generateSmallestTwin((n + 1) / 2);
        }
        // 处理偶数位数情况
        int k = n / 2;
        int[] res = new int[k]; // 存储每个块选择的数字
        Arrays.fill(res, -1);   // 初始化为-1(未选择)
        int prev = -1;          // 前一个块的数字(无前驱时为-1)
        boolean flag = false;   // 是否已大于x
        int i = 0;              // 当前块索引

        // 回溯法选择块
        while (i >= 0 && i < k) {
            if (res[i] != -1) {
                // 回溯重新选择当前块
                int last_choice = res[i];
                res[i] = -1;
                flag = true; // 重新选择会增大,后续可自由选择
                int next_d = -1;
                for (int d = last_choice + 1; d <= 9; d++) {
                    if (i == 0 && d < 1) continue;
                    if (prev != -1 && d == prev) continue;
                    next_d = d;
                    break;
                }
                if (next_d != -1) {
                    res[i] = next_d;
                    prev = next_d;
                    i++; // 处理下一块
                } else {
                    // 当前块无法重新选择,回溯到前一块
                    i--;
                    if (i >= 0) {
                        prev = (i > 0) ? res[i - 1] : -1;
                    }
                }
            } else {
                if (flag) {
                    // 自由选择:选择最小可用数字
                    int start = (i == 0) ? 1 : 0;
                    int d_found = -1;
                    for (int d = start; d <= 9; d++) {
                        if (prev != -1 && d == prev) continue;
                        d_found = d;
                        break;
                    }
                    if (d_found != -1) {
                        res[i] = d_found;
                        prev = d_found;
                        i++;
                    } else {
                        // 理论上自由选择总有解,此处为安全回溯
                        i--;
                        if (i >= 0) {
                            prev = (i > 0) ? res[i - 1] : -1;
                        }
                    }
                } else {
                    // 受限选择:需不小于x的对应部分
                    String twoDigits = x.substring(2 * i, 2 * i + 2);
                    int t = Integer.parseInt(twoDigits);
                    int d_min = (t + 10) / 11; // 向上取整
                    if (i == 0 && d_min < 1) d_min = 1;
                    int d_found = -1;
                    for (int d = d_min; d <= 9; d++) {
                        if (i == 0 && d < 1) continue;
                        if (prev != -1 && d == prev) continue;
                        d_found = d;
                        break;
                    }
                    if (d_found != -1) {
                        res[i] = d_found;
                        if (d_found * 11 > t) flag = true; // 后续可自由选择
                        prev = d_found;
                        i++;
                    } else {
                        // 当前块无解,回溯
                        i--;
                        if (i >= 0) {
                            prev = (i > 0) ? res[i - 1] : -1;
                        }
                    }
                }
            }
        }

        if (i < 0) {
            // n位无解,构造n+2位双生数
            return generateSmallestTwin((n + 2) / 2);
        } else {
            // 构造结果字符串
            StringBuilder sb = new StringBuilder();
            for (int d : res) {
                sb.append(d).append(d);
            }
            return sb.toString();
        }
    }

    // 生成指定块数的最小双生数(交替的"11"和"00"块)
    private static String generateSmallestTwin(int k) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < k; i++) {
            sb.append((i % 2 == 0) ? "11" : "00");
        }
        return sb.toString();
    }
}