- 想了好一阵子才想出一个自认为较简洁的方法,一开始总想着是不是跟排序有关系,经过怎么想也想不出来有什么关系之后发现也只能是模拟骰(tóu)子转动进行穷举。
- 题目要求:按照 上、前、左、右、后、下 的顺序给定两个骰子的颜色,判断两个骰子是否等价。
- 我不喜欢题目给定的这个顺序,没规律,变换时不好写,但是既然都给定了顺序,就凑活凑活吧。
- 解题思路:把上、前、左、右、后、下编号0 1 2 3 4 5,要知道一个骰子(假设6个面都不一样,比如普通骰子)共有24种摆放方式,以普通骰子为例,点数1朝上的情况下有4种,然后点数2朝上......共24种。让6个面都朝上一次,每次中再加一个循环逆时针或顺时针旋转,检验两个骰子是否一样。
- 采用记录数组下标的方式记录变换。例如:设骰子A= {a, b, c, d, e, f}(a-f仅表示某种颜色),那么 "103254" 表示对A进行变换,变换后记作AA = {A[1], A[0], A[3], A[2], A[5], A[4]} = {b, a, d, c, f, e},这样原先a朝上的骰子变为了b朝上,各个面之间相对位置没有改变。其他变换在纸上画一画就能很容易得到。
AC代码如下
#include <bits/stdc++.h>
using namespace std;
char a[15], b[6]; //数组b存储第一个骰子初始状态
int c[] = {0, 2, 4, 1, 3, 5};//水平逆时针旋转所需要的变换
char init[6][7] = {"012345", "103254", "240513", "425031", "351402", "534120"};//6个面分别朝上所需要变换,需要使用数组b,太长所以用字符串表示
bool same() {
for(int i = 0; i < 6; i++)
if(a[i] != a[i + 6])
return false;
return true;
}
void change() {
char temp[6];
for(int i = 0; i < 6; i++)
temp[i] = a[c[i]];
strncpy(a, temp, 6);
}
int main() {
while(cin >> a) {
strncpy(b, a, 6);
bool res = false;
for(int i = 0; i < 6 && !res; i++) {
for(int k = 0; k < 6; k++)
a[k] = b[init[i][k] - '0'];
for(int j = 0; j < 4; j++) {
if(same()) {
res = true;
break;
}
change();
}
}
cout << (res ? "TRUE\n" : "FALSE\n");
}
return 0;
}
2月24日更新:
也可以直接把24种情况的面顺序写出来,然后比较,只要有一种情况相等就是涂色相同。代码更短
代码如下:
#include <iostream>
using namespace std;
const char* state[] = {"012345", "024135", "043215", "031425", "103254", "120534", "152304", "135024", "201453", "215043", "254103", "240513",
"304152", "310542", "351402", "345012", "402351", "425031", "430521", "453201", "513240", "521430", "542310", "534120"};
char color[13];
bool issame(int icase) {
for(int i = 0; i < 6; i++)
if(color[state[icase][i]-'0'] != color[i + 6])
return false;
return true;
}
int main() {
while(cin >> color) {
bool res = false;
for(int i = 0; i < 24; i++)
if(res = issame(i))//如果res为假,继续循环,不影响,为真则直接跳出
break;
cout << (res ? "TRUE\n" : "FALSE\n");
}
return 0;
}
测试提交,可以AC