LA 7735 - Pocket Cube
题目类型:模拟
题意
给定一个二阶魔方每个面的状态,求能否在一步内将魔方还原。
分析
根据题目描述得出每个颜色在输入得数组中得下标。然后就是模拟魔方转动的过程并判断是否还原。思考后可以发现,只有六种转动的情况和一种不转的情况(顺时针转动前面的面等价于逆时针转动后面的面),所以以枚举每种情况进行判断。最好用纸折一个立方体,然后将每个颜色对应的下标写上去调参更方便、准确。
PS:题目数据貌似有问题,输入的 N 应该比实际的测试数据多一个,用 Java 不做处理是过不了的
代码
static int[] top = new int[4];
static int[] front = new int[4];
static int[] bottom = new int[4];
static int[] back = new int[4];
static int[] left = new int[4];
static int[] right = new int[4];
static boolean ok;
public static void solve() throws IOException {
for (int i = 0; i < 4; i++) if (hasNext()) top[i] = nextInt();
for (int i = 0; i < 4; i++) if (hasNext()) front[i] = nextInt();
for (int i = 0; i < 4; i++) if (hasNext()) bottom[i] = nextInt();
for (int i = 0; i < 4; i++) if (hasNext()) back[i] = nextInt();
for (int i = 0; i < 4; i++) if (hasNext()) left[i] = nextInt();
for (int i = 0; i < 4; i++) if (hasNext()) right[i] = nextInt();
ok = isOk();
// x-z
for (int i = 0; i < 4; i++)
fun(top, 0, 2, front, 0, 2, bottom, 0, 2, back, 0, 2, left, 1, i);
// y-z
for (int i = 0; i < 4; i++)
fun(top, 0, 1, right, 0, 1, bottom, 3, 2, left, 0, 1, back, 3, i);
// x-y
for (int i = 0; i < 4; i++)
fun(front, 0, 1, right, 2, 0, back, 3, 2, left, 1, 3, top, 5, i);
pw.println(ok ? "YES" : "NO");
}
public static void fun(int[] a, int a1, int a2, int[] b, int b1, int b2, int[] c, int c1, int c2, int[] d, int d1, int d2, int[] e, int k, int i) {
int t1 = a[a1], t2 = a[a2];
a[a1] = b[b1]; a[a2] = b[b2];
b[b1] = c[c1]; b[b2] = c[c2];
c[c1] = d[d1]; c[c2] = d[d2];
d[d1] = t1; d[d2] = t2;
switch (k) {
case 1: turn(e, 1, 3, 2, 0); break;
case 3: turn(e, 2, 3, 1, 0); break;
case 5: turn(e, 1, 0, 2, 3); break;
}
if (i == 0 || i == 2) ok |= isOk();
}
public static void turn(int[] e, int a1, int a2, int a3, int a4) {
int t = e[a1];
e[a1] = e[a2];
e[a2] = e[a3];
e[a3] = e[a4];
e[a4] = t;
}
public static boolean isOk() {
for (int i = 1; i < 4; i++) if (top[i] != top[i - 1]) return false;
for (int i = 1; i < 4; i++) if (front[i] != front[i - 1]) return false;
for (int i = 1; i < 4; i++) if (bottom[i] != bottom[i - 1]) return false;
for (int i = 1; i < 4; i++) if (back[i] != back[i - 1]) return false;
for (int i = 1; i < 4; i++) if (left[i] != left[i - 1]) return false;
for (int i = 1; i < 4; i++) if (right[i] != right[i - 1]) return false;
return true;
}