解法
- 条件に反さないように立方体を置き、とりあえず立体を作る。
- 全ての立方体が接続されているとは限らないので、接続されている立体ごとに分け、その中に条件を満たすものが存在するかどうか確かめる。
コード
import java.util.ArrayDeque;
import java.util.Deque;
public class ShadowSculpture {
public String possible(String[] XY, String[] YZ, String[] ZX) {
int N = XY.length;
int[][] dir = { { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 }, { 0, 0, -1 }, { 0, -1, 0 }, { -1, 0, 0 } };
boolean[][][] cubes = new boolean[N][N][N];
for (int x = 0; x < N; x++) {
for (int y = 0; y < N; y++) {
for (int z = 0; z < N; z++) {
char xy = XY[x].charAt(y);
char yz = YZ[y].charAt(z);
char zx = ZX[z].charAt(x);
if (xy == 'Y' && yz == 'Y' && zx == 'Y') {
cubes[x][y][z] = true;
}
}
}
}
if (!check(N, XY, YZ, ZX, cubes)) {
return "Impossible";
}
if (check(N, XY, YZ, ZX, new boolean[N][N][N])) {
return "Possible";
}
boolean[][][] used = new boolean[N][N][N];
for (int x = 0; x < N; x++) {
for (int y = 0; y < N; y++) {
for (int z = 0; z < N; z++) {
if (!used[x][y][z] && cubes[x][y][z]) {
boolean[][][] testCubes = new boolean[N][N][N];
testCubes[x][y][z] = true;
used[x][y][z] = true;
Deque<Integer[]> deque = new ArrayDeque<>();
deque.add(new Integer[] { x, y, z });
while (!deque.isEmpty()) {
Integer[] p = deque.poll();
int px = p[0];
int py = p[1];
int pz = p[2];
for (int d = 0; d < 6; d++) {
int i = px + dir[d][0];
int j = py + dir[d][1];
int k = pz + dir[d][2];
if (i < 0 || j < 0 || k < 0 || i >= N || j >= N || k >= N) {
continue;
}
if (cubes[i][j][k] && !used[i][j][k]) {
testCubes[i][j][k] = true;
used[i][j][k] = true;
deque.add(new Integer[] { i, j, k });
}
}
}
if (check(N, XY, YZ, ZX, testCubes)) {
return "Possible";
}
}
}
}
}
return "Impossible";
}
boolean check(int N, String[] XY, String[] YZ, String[] ZX, boolean[][][] cubes) {
for (int x = 0; x < N; x++) {
for (int y = 0; y < N; y++) {
if (XY[x].charAt(y) == 'Y') {
boolean checked = false;
for (int z = 0; z < N; z++) {
if (cubes[x][y][z]) {
checked = true;
break;
}
}
if (!checked) {
return false;
}
}
}
}
for (int y = 0; y < N; y++) {
for (int z = 0; z < N; z++) {
if (YZ[y].charAt(z) == 'Y') {
boolean checked = false;
for (int x = 0; x < N; x++) {
if (cubes[x][y][z]) {
checked = true;
break;
}
}
if (!checked) {
return false;
}
}
}
}
for (int z = 0; z < N; z++) {
for (int x = 0; x < N; x++) {
if (ZX[z].charAt(x) == 'Y') {
boolean checked = false;
for (int y = 0; y < N; y++) {
if (cubes[x][y][z]) {
checked = true;
break;
}
}
if (!checked) {
return false;
}
}
}
}
return true;
}
}