原题地址:https://codeforces.com/contest/887/problem/C
题意:给出一个的魔方,问你能否旋转且仅旋转一次使得魔方还原.
思路:冷静分析之后可以知道,对于一个初始的魔方,有且仅有六种方法去旋转一次,因此我们只需要去模拟就行了.
#include <bits/stdc++.h>
#include <cmath>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <map>
#include <cctype>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cout<<"["<<"x = "<<(x)<<"] "
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed=131;
const int maxn=2e5+5;
int a[25];
int r[3][8]= {{1,3,5,7,9,11,24,22},{13,14,5,6,17,18,21,22},{3,4,17,19,10,9,16,14}};
//代表着三种旋转方式
void rot(int k) { //第k种方式旋转一次,旋转其实就是将当前位置+2
int a1=a[r[k][0]],a2=a[r[k][1]];
for(int i=0; i<6; i++) {
a[r[k][i]]=a[r[k][i+2]];
}
a[r[k][6]]=a1;
a[r[k][7]]=a2;
}
//判断每面颜色是否单一
bool check() {
for(int i=0; i<6; i++) {
for(int j=1; j<4; j++) {
if(a[i*4+j]!=a[i*4+j+1]) return false;
}
}
return true;
}
int main() {
for(int i=1; i<=24; i++) scanf("%d",&a[i]);
for(int i=0; i<3; i++) {
rot(i);//第一次旋转
if(check()) {
printf("YES\n");
return 0;
}
rot(i);
rot(i);//再做两次旋转,相当于往回转一次
if(check()) {
printf("YES\n");
return 0;
}
rot(i);//最后一次旋转,回归原样
}
printf("NO\n");
return 0;
}