一、游游的重组偶数

Java代码

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    // 纯数学运算实现 dep 函数,和你C++逻辑完全一样
    public static int dep(int x) {
        int temp = x;
        int k = 0;
        // 保存最后一位数字
        int last = x % 10;
        
        while (temp > 0) {
            int t = temp % 10;
            // 找到第一个偶数位
            if (t % 2 == 0) {
                // 计算 10^k
                int pow10 = 1;
                for (int i = 0; i < k; i++) {
                    pow10 *= 10;
                }
                // 构造新数字:和你C++公式完全一样
                int res = x - t * pow10 + last * pow10 - last + t;
                return res;
            }
            temp /= 10;
            k++;
        }
        // 没找到偶数
        return -1;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int q = in.nextInt();
        while (q-- > 0) {
            int x = in.nextInt();
            if (x % 2 == 0) {
                System.out.println(x);
            } else {
                System.out.println(dep(x));
            }
        }
        in.close();
    }
}

分析:逻辑非常清楚,读到一个数据就判断一次,如果是偶数直接返回,是奇数判断后再返回

1.Scanner 键盘输入:读取多组整数数据-->while(q--)

            while (q-- > 0) {
            int x = in.nextInt();
            if (x % 2 == 0) {
                System.out.println(x);
            } else {
                System.out.println(dep(x));
                }
            }
        

2.dep 方法:处理奇数重组数字

    public static int dep(int x) {
        int temp = x;
        int k = 0;
        // 保存最后一位数字
        int last = x % 10;
        
        while (temp > 0) {
            int t = temp % 10;
            // 找到第一个偶数位
            if (t % 2 == 0) {
                // 计算 10^k
                int pow10 = 1;
                for (int i = 0; i < k; i++) {
                    pow10 *= 10;
                }
                // 构造新数字:和你C++公式完全一样
                int res = x - t * pow10 + last * pow10 - last + t;
                return res;
            }
            temp /= 10;
            k++;
        }
        // 没找到偶数
        return -1;
    }

例子:x = 123(奇数)

  • 最后一位 last = 3
  • 数字:1 2 3
  • 从右找:3 (奇) → 2 (偶)!找到啦!

计算过程

  • t = 2(偶数)
  • pow10 = 10(十位)
  • 公式:123 - 210 + 310 - 3 + 2= 123 -20 +30 -3 +2= 132

逐行精解

// 功能:处理奇数 x,返回交换后的新数,没偶数返回-1
public static int dep(int x) {
    int temp = x;   // 临时备份 x,用来逐位拆数字,不破坏原数 x
    int k = 0;      // 记录:当前正在看第几位(从右数,个位=0,十位=1...)
    int last = x % 10; // 固定取出:数字的最后一位(后面要用来交换)

1. 循环:从右往左,一位一位检查数字

    while (temp > 0) {      // 只要还有数字没看完,就继续
        int t = temp % 10;  // 【关键】取出当前最右边的一位数字
  • temp % 10:永远取最后一位
  • 这是拆数字的标准写法
        if (t % 2 == 0) {   // 如果这一位是偶数!找到了!

2. 计算当前位的权重(10 的多少次方)

            int pow10 = 1;
            for (int i = 0; i < k; i++) {
                pow10 *= 10;
            }
  • 作用:算出当前位代表多大
    • 个位:10⁰ = 1
    • 十位:10¹ = 10
    • 百位:10² = 100
  • 不用 Math.pow() 是避免浮点数精度出错

3. 计算当前位的权重(10 的多少次方)

            int res = x - t * pow10 + last * pow10 - last + t;
            return res;     // 交换完成,直接返回新数
        }

二、体操队形

深度优先搜索

import java.util.Scanner;

public class Main {
    // 全局变量(和 C++ 全局变量作用一样)
    static int ret;       // 答案:合法方案数
    static int n;         // 人数
    static boolean[] vis; // 标记是否用过
    static int[] arr;     // 存储输入的数组

    // DFS 深度优先搜索(和你 C++ 的 dfs 完全一样)
    public static void dfs(int pos) {
        // 递归出口:排完了所有人,计数+1
        if (pos == n + 1) {
            ret++;
            return;
        }

        // 遍历 1~n 尝试放每一个人
        for (int i = 1; i <= n; i++) {
            if (vis[i]) continue;        // 已经用过,跳过
            if (vis[arr[i]]) return;    // 剪枝(原题核心条件)

            vis[i] = true;             // 标记使用
            dfs(pos + 1);              // 递归下一个位置
            vis[i] = false;            // 回溯:撤销标记
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // 初始化变量(对应 C++ 全局变量)
        n = sc.nextInt();
        arr = new int[n + 1];  // 从 1 开始存,方便和 C++ 对应
        vis = new boolean[n + 1];
        ret = 0;

        // 读入数组
        for (int i = 1; i <= n; i++) {
            arr[i] = sc.nextInt();
        }

        dfs(1); // 从第 1 个位置开始搜

        System.out.println(ret);
    }
}

更多推荐