1. 题目
读题
考查点
2. 解法
思路
代码逻辑
具体实现
import java.util.Scanner;
import java.util.Arrays;
public class HJ67 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int[] nums = new int[4];
for (int i = 0; i < 4; i++) {
nums[i] = sc.nextInt();
}
System.out.println(solve(nums));
}
sc.close();
}
public static boolean solve(int[] nums) {
Arrays.sort(nums); // 排序
do {
if (check(nums)) return true; // 检查当前排列是否满足条件
} while (nextPermutation(nums)); // 生成下一个排列
return false;
}
public static boolean check(int[] nums) {
for (int i = 0; i < 4; i++) { // 枚举第一个运算符
for (int j = 0; j < 4; j++) { // 枚举第二个运算符
for (int k = 0; k < 4; k++) { // 枚举第三个运算符
double a = calc(nums[0], nums[1], i); // 计算第一个表达式
double b = calc(a, nums[2], j); // 计算第二个表达式
double c = calc(b, nums[3], k); // 计算第三个表达式
if (Math.abs(c - 24) < 1e-6) return true; // 如果结果等于24,返回true
a = calc(nums[0], nums[1], i); // 计算第一个表达式
b = calc(nums[2], nums[3], k); // 计算第三个表达式
c = calc(a, b, j); // 计算第二个表达式(考虑括号)
if (Math.abs(c - 24) < 1e-6) return true; // 如果结果等于24,返回true
}
}
}
return false;
}
public static double calc(double x, double y, int op) { // 根据运算符计算两个数的结果
switch (op) {
case 0: return x + y;
case 1: return x - y;
case 2: return x * y;
case 3: return x / y;
default: return 0;
}
}
public static boolean nextPermutation(int[] nums) { // 生成下一个排列(字典序)
int n = nums.length;
int i = n - 2;
while (i >= 0 && nums[i] >= nums[i + 1]) { // 找到第一个逆序对
i--;
}
if (i >= 0) { // 如果不是最后一个排列
int j = n - 1;
while (j > i && nums[j] <= nums[i]) { // 找到第一个大于nums[i]的数
j--;
}
swap(nums, i, j); // 交换两个数
} else { // 如果是最后一个排列,返回false
return false;
}
reverse(nums, i + 1, n - 1); // 反转后面的部分
return true;
}
public static void swap(int[] nums, int i, int j) { // 交换数组中两个数的位置
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public static void reverse(int[] nums, int i, int j) { // 反转数组中一段区间的元素
while (i < j) {
swap(nums, i, j);
i++;
j--;
}
}
}