思路:
”例如有一个 4×4×4 的大方块,其体积为 64;给出参数 (1,1,1),(2,2,2) 时,中间的 8 块小方块就会被蒸发,剩下 56 个小方块。“,中间的 8 块小方块是(1,1,1),(1,1,2),(1,2,1),(1,2,2),(2,1,1),(2,1,2),(2,2,1),(2,2,2).
切除立方体空洞。说明需要标志位flag来表明该点是否已被切割,因为坐标是3维,使用2维不好表示坐标,所以falg数组定义为3维数组。
注意最后的说明提示,w1≤x1≤x2≤w, x1≤y1≤y2≤x,h1≤z1≤z2≤h。说明如果定义数组的长度是是arr[w][x][h]就不能直接使用输入的x1,y1,z1,x2,y2,z2。
就是说,不能这样:
for(int i = x1; i <= x2; i++) {
for(int j = y1; j <= y2; j++) {
for(int k = z1; k <= z2; k++) {
if(flag[i][j][k])
flag[i][j][k] = false;
}
}
}
}
因为x1,x2可能会等于w;y1,y2可能会等于x;z1,z2可能会等于h,这意味着下标可能会越界
要么定义arr的时候长度定义为arr[w+1][x+1][h+1],此时下标从1 开始:
int[][][] arr = new int[w + 1][x + 1][h + 1];
要么这么使用x1,y1,z1,x2,y2,z2:
for(int i = x1-1; i < x2; i++) {
for(int j = y1-1; j < y2; j++) {
for(int k = z1-1; k < z2; k++) {
if(flag[i][j][k])
flag[i][j][k] = false;
}
}
}
}
代码:
package 数组;
import java.util.Scanner;
public class P5729 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int w = sc.nextInt();
int x = sc.nextInt();
int h = sc.nextInt();
boolean [][][]flag = new boolean[w][x][h];
for(int i = 0; i < w; i++) {
for(int j = 0; j < x; j++) {
for(int k = 0; k < h; k++) {
flag[i][j][k] = true;
}
}
}
int q = sc.nextInt();
while(q-- > 0) {
int x1 = sc.nextInt();
int y1 = sc.nextInt();
int z1 = sc.nextInt();
int x2 = sc.nextInt();
int y2 = sc.nextInt();
int z2 = sc.nextInt();
for(int i = x1-1; i < x2; i++) {
for(int j = y1-1; j < y2; j++) {
for(int k = z1-1; k < z2; k++) {
if(flag[i][j][k])
flag[i][j][k] = false;
}
}
}
}
int cnt = 0;
for(int i = 0; i < w; i++) {
for(int j = 0; j < x; j++) {
for(int k = 0; k < h; k++) {
if(flag[i][j][k]) cnt++;
}
}
}
System.out.print(cnt);
}
}
反思:
没有注意最后的说明提示部分,导致下标越界了。