题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5983
题意:2*2*2的魔方只转一次,问是否能让魔方六面都相等
思路:
用数组记录每个面的数字,并且从1到24编号,注意这里要根据题目要求的输入顺序编号,能一次就完成任务的情况只有两种,一种是六面都已经满足条件了,第二种是存在两个对立面相等的情况,只限两个,多一个都不行;对立面相等的不用管,只需要转动除对立面的另外四个面就行了,转的方式有两种,一种是顺时针一种是逆时针;
#include <iostream>
using namespace std;
int a[30];
bool check (int x, int y, int xx, int yy) {
if(x == y && xx == yy && x == xx) return true;
else return false;
}
int main (void)
{
int N;
cin >> N;
while (N--) {
int cnt = 0;
for (int i = 1; i <= 21; i+=4) {
cin >> a[i] >> a[i+1] >> a[i+2] >> a[i+3];
if(check (a[i], a[i+1], a[i+2], a[i+3])) cnt++;
}
if(cnt == 6) {
cout << "YES" << endl; continue;
} else if(cnt != 2) {
cout << "NO" << endl; continue;
}
bool falg = false;
if(check (a[1], a[2], a[3], a[4]) && check (a[9], a[10], a[11], a[12])) {
if(check (a[20], a[18], a[13], a[14]) && check (a[15], a[16], a[22], a[24]) &&
check (a[21], a[23], a[7], a[8]) && check (a[5], a[6], a[17], a[19])) falg = true;
if(check (a[19], a[17], a[15], a[16]) && check (a[13], a[14], a[21], a[23]) &&
check (a[22], a[24], a[5], a[6]) && check (a[7], a[8], a[18], a[20])) falg = true;
}
else if(check (a[17], a[18], a[19], a[20]) && check (a[21], a[22], a[23], a[24])) {
if(check (a[2], a[4], a[5], a[7]) && check (a[6], a[8], a[9], a[11]) &&
check (a[10], a[12], a[13], a[15]) && check (a[14], a[16], a[1], a[3])) falg = true;
if(check (a[1], a[3], a[6], a[8]) && check (a[5], a[7], a[10], a[12]) &&
check (a[9], a[11], a[14], a[16]) && check (a[13], a[15], a[2], a[4])) falg = true;
}
else if(check (a[5], a[6], a[7], a[8]) && check (a[13], a[14], a[15], a[16])) {
if(check (a[19], a[20], a[1], a[2]) && check (a[3], a[4], a[21], a[22]) &&
check (a[23], a[24], a[11], a[12]) && check (a[9], a[10], a[17], a[18])) falg = true;
if(check (a[17], a[18], a[3], a[4]) && check (a[1], a[2], a[23], a[24]) &&
check (a[21], a[22], a[9], a[10]) && check (a[11], a[12], a[19], a[20])) falg = true;
}
if(falg) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}