差分和前缀和互为逆运算,这个题用三维差分,三维只是比较麻烦,和容斥原理比较类似。
Problem
好像是A组第六题,蓝桥杯省赛第六题居然已经这么难了?
因为保证矩阵行列相乘小于1e6但不知道行和列分别有多大,所以需要用到数组下标映射,也就是代码中的
public static int get(int i, int j, int k){...}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(System.out);
static int N = 2000010, A, B, C, m;
static long s[] = new long[N], b[] = new long[N], bp[] = new long[N];
static int op[][] = new int[N >> 1][7];
static int d[][] = new int[][]{
{0, 0, 0, 1},
{0, 0, 1, -1},
{0, 1, 0, -1},
{0, 1, 1, 1},
{1, 0, 0, -1},
{1, 0, 1, 1},
{1, 1, 0, 1},
{1, 1, 1, -1},
};
public static void main(String[] args) throws Exception {
String ss[] = br.readLine().split(" ");
A = Integer.parseInt(ss[0]);
B = Integer.parseInt(ss[1]);
C = Integer.parseInt(ss[2]);
m = Integer.parseInt(ss[3]);
ss = br.readLine().split(" ");
int uu = 0;
for (int i = 1; i <= A; i++) {
for (int j = 1; j <= B; j++) {
for (int k = 1; k <= C; k++) {
s[get(i, j, k)] = Long.parseLong(ss[uu++]);
}
}
}
for (int i = 1; i <= A; i++) {
for (int j = 1; j <= B; j++) {
for (int k = 1; k <= C; k++) {
for (int u = 0; u < 8; u++) {
int x = i - d[u][0];
int y = j - d[u][1];
int z = k - d[u][2];
int t = d[u][3];
bp[get(i, j, k)] += s[get(x, y, z)] * t;
}
}
}
}
for (int i = 1; i <= m; i++) {
ss = br.readLine().split(" ");
for (int j = 0; j < 7; j++)
op[i][j] = Integer.parseInt(ss[j]);
}
int l = 1, r = m;
while (l < r) {
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
pw.print(r);
pw.flush();
pw.close();
br.close();
}
public static int get(int i, int j, int k) {
return (i * B + j) * C + k;
}
public static boolean check(int mid) {
b = Arrays.copyOf(bp, bp.length);
for (int i = 1; i <= mid; i++) {
int x1 = op[i][0];
int x2 = op[i][1];
int y1 = op[i][2];
int y2 = op[i][3];
int z1 = op[i][4];
int z2 = op[i][5];
int t = op[i][6];
b[get(x1 , y1 , z1 )] -= t;
b[get(x1 , y1 , z2 + 1)] += t;
b[get(x1 , y2 + 1, z1 )] += t;
b[get(x1 , y2 + 1, z2 + 1)] -= t;
b[get(x2 + 1, y1 , z1 )] += t;
b[get(x2 + 1, y1 , z2 + 1)] -= t;
b[get(x2 + 1, y2 + 1, z1 )] -= t;
b[get(x2 + 1, y2 + 1, z2 + 1)] += t;
}
Arrays.fill(s, 0);
for (int i = 1; i <= A; i++) {
for (int j = 1; j <= B; j++) {
for (int k = 1; k <= C; k++) {
s[get(i, j, k)] = b[get(i, j, k)];
for (int u = 1; u < 8; u++) {
int x = i - d[u][0];
int y = j - d[u][1];
int z = k - d[u][2];
int t = d[u][3];
s[get(i, j, k)] -= s[get(x, y, z)] * t;
}
if (s[get(i, j, k)] < 0) return true;
}
}
}
return false;
}
}
SoKeeGanCN
发布了153 篇原创文章 · 获赞 3 · 访问量 2716
私信
关注