一、游游的重组偶数
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); } }