Java算法练习day3
·
一、游游的重组偶数
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);
}
}
更多推荐





所有评论(0)