2.5h三道编程题,时间比较充裕。
第一题是
模拟
,比一般的模拟麻烦一些,细心点是没问题的。
第二题01 背包
,状态最少也有三维,必须空间压缩。数据会溢出所以得用long
存。
第三题二维差分
,最后ac 了 70%,怀疑是java 选手被针对了,用 c++写应该就 ac 了。
第一题
package wy1;
import java.util.*;
public class Main {
static final int N = 5; // 式神的数量
static int[] a = new int[N]; // 小易的式神攻击力
static int[] b = new int[N]; // 小易的式神血量
static int[] c = new int[N]; // 对手的式神攻击力
static int[] d = new int[N]; // 对手的式神血量
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 读取小易的式神的攻击力
for (int i = 0; i < 5; i++)
a[i] = sc.nextInt();
// 读取小易的式神的血量
for (int i = 0; i < 5; i++)
b[i] = sc.nextInt();
// 读取对手的式神的攻击力
for (int i = 0; i < 5; i++)
c[i] = sc.nextInt();
// 读取对手的式神的血量
for (int i = 0; i < 5; i++)
d[i] = sc.nextInt();
int i = 0, j = 0, order = 0; // 初始化索引和攻击顺序
while (i < 5 && j < 5) {
// 计算对手能承受的攻击次数
int su_op = d[j] / a[i] + ((d[j] % a[i]) == 0 ? 0 : 1);
// 计算自己能承受的攻击次数
int su_zj = b[i] / c[j] + ((b[i] % c[j]) == 0 ? 0 : 1);
if (order == 0) { // 小易的攻击回合
if (b[i] > (su_op - 1) * c[j]) { // 小易当前赢
b[i] -= (su_op - 1) * c[j];
j++;
order = 1;
} else { // 小易当前输
d[j] -= su_zj * a[i];
i++;
order = 0;
}
} else { // 对手的攻击回合
if (d[j] > (su_zj - 1) * a[i]) { // 对方当前赢
d[j] -= (su_zj - 1) * a[i];
i++;
order = 0;
} else { // 对方当前输
b[i] -= su_op * c[j];
j++;
order = 1;
}
}
}
if (j == 5) {
System.out.println("win"); // 小易获胜
System.out.println(5 - i); // 小易存活的式神数量
} else {
System.out.println("lose"); // 小易失败
System.out.println(5 - j); // 对手存活的式神数量
}
}
}
过了 95% 就没管了直接下一道了
第二题
package wy2;
import java.util.*;
public class Main {
static final int INF = Integer.MIN_VALUE; // 定义负无穷大,用于初始化 dp 数组
static final int MAX_N = 410; // 最大建筑数量
static final int MAX_A = 55; // 最大石灰岩数量
static final int MAX_B = 55; // 最大砂岩数量
static final int MAX_C = 55; // 最大花岗岩数量
static int n, A, B, C; // 建筑数量及初始资源数量
static int[] a = new int[MAX_N]; // 每个建筑的石灰岩消耗
static int[] b = new int[MAX_N]; // 每个建筑的砂岩消耗
static int[] c = new int[MAX_N]; // 每个建筑的花岗岩消耗
static int[] v = new int[MAX_N]; // 每个建筑的收益
static long[][][] dp = new long[MAX_A][MAX_B][MAX_C]; // 三维 dp 数组,存储最大收益
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt(); // 输入建筑数量
A = sc.nextInt(); // 输入石灰岩数量
B = sc.nextInt(); // 输入砂岩数量
C = sc.nextInt(); // 输入花岗岩数量
// 输入每个建筑的资源消耗和收益
for (int i = 1; i <= n; i++) {
a[i] = sc.nextInt();
b[i] = sc.nextInt();
c[i] = sc.nextInt();
v[i] = sc.nextInt();
}
// 初始化 dp 数组
for (int i = 0; i <= A; i++) {
for (int j = 0; j <= B; j++) {
for (int k = 0; k <= C; k++) {
dp[i][j][k] = INF; // 初始化为负无穷大
}
}
}
dp[0][0][0] = 0; // 初始状态,不使用任何资源时收益为0
// 动态规划状态转移
for (int i = 1; i <= n; i++) {
for (int j = A; j >= a[i]; j--) {
for (int k = B; k >= b[i]; k--) {
for (int l = C; l >= c[i]; l--) {
dp[j][k][l] = Math.max(dp[j][k][l], dp[j - a[i]][k - b[i]][l - c[i]] + v[i]);
}
}
}
}
// 计算最大收益
long result = 0;
for (int i = 0; i <= A; i++) {
for (int j = 0; j <= B; j++) {
for (int k = 0; k <= C; k++) {
result = Math.max(result, dp[i][j][k]);
}
}
}
System.out.println(result); // 输出最大收益
}
}
第三题
package wy3;
import java.util.*;
public class Main {
static final int N = 2010, OFFSET = 1000;
static int[][] a = new int[N][N]; // 用于存储最终影响范围的数组
static int[][] b = new int[N][N]; // 用于拆分的辅助数组
static int n, q;
// 在矩形区域内进行差分操作
static void insert(int x1, int y1, int x2, int y2, int c) {
b[x1][y1] += c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y1] -= c;
b[x2 + 1][y2 + 1] += c;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt(); // 读取建筑数量
// 处理每个建筑的影响范围
for (int i = 0; i < n; i++) {
int x = sc.nextInt() + OFFSET; // 读取并平移 x 坐标
int y = sc.nextInt() + OFFSET; // 读取并平移 y 坐标
int r = sc.nextInt(); // 读取影响半径
// 在影响范围内进行差分操作
insert(x - r, y - r, x + r, y + r, 1);
}
// 计算前缀和数组
for (int i = 1; i < N; i++) {
for (int j = 1; j < N; j++) {
a[i][j] = b[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
}
}
q = sc.nextInt(); // 读取查询数量
// 处理每个查询
for (int i = 0; i < q; i++) {
int x = sc.nextInt() + OFFSET; // 读取并平移查询点的 x 坐标
int y = sc.nextInt() + OFFSET; // 读取并平移查询点的 y 坐标
System.out.println(a[x][y]); // 输出查询点的影响值
}
}
}
牛啊,一点小建议:(1)错别字 :二维拆分 → 二维差分(2)状态压缩的意思一般是用二进制代表一种状态
Orz感谢大佬提醒Orz
(1)差分,大意了(2)从一开始就搞错了,已修正~
yyds