HDU 5983 - Pocket Cube(模拟)

Pocket Cube


Problem Description
The Pocket Cube, also known as the Mini Cube or the Ice Cube, is the 2 × 2 × 2 equivalence of a Rubik’s Cube.The cube consists of 8 pieces, all corners.Each piece is labeled by a three dimensional coordinate (h, k, l) where h, k, l ∈ {0, 1}. Each of the six faces owns four small faces filled with a positive integer.For each step, you can choose a certain face and turn the face ninety degrees clockwise or counterclockwise.You should judge that if one can restore the pocket cube in one step. We say a pocket cube has been restored if each face owns four same integers.
 

Input
The first line of input contains one integer N(N ≤ 30) which is the number of test cases.For each test case, the first line describes the top face of the pocket cube, which is the common 2 × 2 face of pieceslabelled by (0, 0, 1),(0, 1, 1),(1, 0, 1),(1, 1, 1). Four integers are given corresponding to the above pieces.The second line describes the front face, the common face of (1, 0, 1),(1, 1, 1),(1, 0, 0),(1, 1, 0). Four integers aregiven corresponding to the above pieces.The third line describes the bottom face, the common face of (1, 0, 0),(1, 1, 0),(0, 0, 0),(0, 1, 0). Four integers aregiven corresponding to the above pieces.The fourth line describes the back face, the common face of (0, 0, 0),(0, 1, 0),(0, 0, 1),(0, 1, 1). Four integers aregiven corresponding to the above pieces.The fifth line describes the left face, the common face of (0, 0, 0),(0, 0, 1),(1, 0, 0),(1, 0, 1). Four integers are givencorresponding to the above pieces.The six line describes the right face, the common face of (0, 1, 1),(0, 1, 0),(1, 1, 1),(1, 1, 0). Four integers are givencorresponding to the above pieces.In other words, each test case contains 24 integers a, b, c to x. You can flat the surface to get the surface developmentas follows.
+ - + - + - + - + - + - +
| q | r | a | b | u | v |
+ - + - + - + - + - + - +
| s | t | c | d | w | x |
+ - + - + - + - + - + - +
        | e | f |
        + - + - +
        | g | h |
        + - + - +
        | i | j |
        + - + - +
        | k | l |
        + - + - +
        | m | n |
        + - + - +
        | o | p |
        + - + - +
 

Output
For each test case, output YES if can be restored in one step, otherwise output NO.
 

Sample Input
4
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
5 5 5 5
6 6 6 6
6 6 6 6
1 1 1 1
2 2 2 2
3 3 3 3
5 5 5 5
4 4 4 4
1 4 1 4
2 1 2 1
3 2 3 2
4 3 4 3
5 5 5 5
6 6 6 6
1 3 1 3
2 4 2 4
3 1 3 1
4 2 4 2
5 5 5 5
6 6 6 6
 

Sample Output
YES
YES
YES
NO
【题意】
    给定一个二阶魔方,按照描述中的a-z的顺序输入每个面的颜色(数字),判断这个魔方能否在一步以内被还原,这里的一步是指任意的一个平面顺时针或逆时针旋转90度。
【思路】
    用6个数组存储每个面对应4个小块的颜色,然后枚举所有的旋转方式,判断是否存在一种旋转方式可以是魔方还原,注意旋转的相对性,比如把顶面从左往右转其实和把底面从右往左转是一样的,所以只有6中旋转方法,加上不做任何旋转共7中。但是这道题对细节要求很高,一不小心就会写错,所以最好用纸剪一个模型出来看着写不容易错,不然WA了的话找错都很难。
【代码】
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

int iup[4], ifront[4], idown[4], iback[4], ile[4], iri[4];//输入
int up[4], front[4], down[4], back[4], le[4], ri[4];//计算

void input() {
	for (int i = 0; i < 4; i++) scanf("%d", &iup[i]);
	for (int i = 0; i < 4; i++) scanf("%d", &ifront[i]);
	for (int i = 0; i < 4; i++) scanf("%d", &idown[i]);
	for (int i = 0; i < 4; i++) scanf("%d", &iback[i]);
	for (int i = 0; i < 4; i++) scanf("%d", &ile[i]);
	for (int i = 0; i < 4; i++) scanf("%d", &iri[i]);
}

void cpy() {
	memcpy(up, iup, sizeof(up));
	memcpy(front, ifront, sizeof(front));
	memcpy(down, idown, sizeof(down));
	memcpy(back, iback, sizeof(back));
	memcpy(le, ile, sizeof(le));
	memcpy(ri, iri, sizeof(ri));
}

bool check() {
	if (up[0] != up[1] || up[0] != up[2] || up[0] != up[3]) return false;
	if (front[0] != front[1] || front[0] != front[2] || front[0] != front[3]) return false;
	if (down[0] != down[1] || down[0] != down[2] || down[0] != down[3]) return false;
	if (back[0] != back[1] || back[0] != back[2] || back[0] != back[3]) return false;
	if (le[0] != le[1] || le[0] != le[2] || le[0] != le[3]) return false;
	if (ri[0] != ri[1] || ri[0] != ri[2] || ri[0] != ri[3]) return false;
	return true;
}

bool r0() { cpy(); return check(); }//不做任何旋转

bool r1() {//上下不动,从右往左
	cpy();
	int f0 = front[0], f1 = front[1];

	front[0] = ri[2],	front[1] = ri[0];
	ri[2] = back[3],	ri[0] = back[2];
	back[3] = le[1],	back[2] = le[3];
	le[1] = f0,			le[3] = f1;

	return check();
}

bool r2() {//上下不动,从左往右
	cpy();
	int f0 = front[0], f1 = front[1];

	front[0] = le[1],	front[1] = le[3];
	le[1] = back[3],	le[3] = back[2];
	back[3] = ri[2],	back[2] = ri[0];
	ri[2] = f0,			ri[0] = f1;

	return check();
}

bool r3() {//左右不动,从前往后
	cpy();
	int f0 = front[0], f2 = front[2];

	front[0] = down[0], front[2] = down[2];
	down[0] = back[0],	down[2] = back[2];
	back[0] = up[0],	back[2] = up[2];
	up[0] = f0,			up[2] = f2;

	return check();
}

bool r4() {//左右不动,从后往前
	cpy();
	int f0 = front[0], f2 = front[2];

	front[0] = up[0],	front[2] = up[2];
	up[0] = back[0],	up[2] = back[2];
	back[0] = down[0],	back[2] = down[2];
	down[0] =			f0, down[2] = f2;

	return check();
}

bool r5() {//前后不动,从左往右
	cpy();
	int u0 = up[0], u1 = up[1];

	up[0] = le[0],		up[1] = le[1];
	le[0] = down[3],	le[1] = down[2];
	down[3] = ri[0],	down[2] = ri[1];
	ri[0] = u0,			ri[1] = u1;

	return check();
}

bool r6() {//前后不动,从右往左
	cpy();
	int u0 = up[0], u1 = up[1];

	up[0] = ri[0],		up[1] = ri[1];
	ri[0] = down[3],	ri[1] = down[2];
	down[3] = le[0],	down[2] = le[1];
	le[0] = u0,			le[1] = u1;

	return check();
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		input();
		bool flag = r0() || r1() || r2() || r3() || r4() || r5() || r6();
		printf("%s\n", flag ? "YES" : "NO");
	}
	return 0;
}

posted @ 2017-10-22 17:33  不想吃WA的咸鱼  阅读(358)  评论(0编辑  收藏  举报