/* 法一: 设所给的两个面为a、b,将b固定,对a进行颠倒、旋转的有关处理,如下: 对a,循环考虑6种情况,分别是6个面作为上面的情况 在这6种情况中,每种都要进行3次旋转,也就是考虑4种情况(固定上下面的情况下,其他4个面,都要作为正面1次) 思路来自blog: http://blog.csdn.net/qq_18738333/article/details/44968341 */
#include <iostream> #include <cstring> using namespace std; const int N = 20; char a[N], b[N], s[N]; int dir[6][6] = { { 0, 1, 2, 3, 4, 5 }, { 1, 5, 2, 3, 0, 4 }, { 2, 1, 5, 0, 4, 3 }, { 3, 1, 0, 5, 4, 2 }, { 4, 5, 3, 2, 0, 1 }, { 5, 1, 3, 2, 4, 0 } }; bool judge() { char tp[10]; // temp; for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) tp[j] = a[dir[i][j]]; // 将骰子的状态,置为编号所代表的面为正方体上面 tp[6] = 0; for (int i = 0; i < 4; i++) //除去上面和下面以外,剩下的4个面,轮流做前面 { char ch = tp[1]; tp[1] = tp[2]; tp[2] = tp[4]; tp[4] = tp[3]; tp[3] = ch; if (!strcmp(tp, b)) return true; } } return false; } int main() { while (cin >> s) { for (int i = 0; i < 6; i++) a[i] = s[i]; for (int i = 0; i < 6; i++) b[i] = s[6 + i]; a[6] = b[6] = 0; if (judge()) cout << "TRUE" << endl; else cout << "FALSE" << endl; } return 0; }
/* 法二: 法二真是看问题直抓本质的一种方法,初次搜索后看到时,简直觉得惊为天人啊!(此处成语好像运用不得当,不要在意这些细节,反正就是十分惊叹...) 总结一下法二,法二就是,根本不旋转、颠倒,而是找规律:何时两个正方形等价? 它们的6个面,可以组成3组相对的面,只要判断2个正方形的3个对立面是否一致即可 思路来自blog: http://blog.csdn.net/qq_20480611/article/details/48899907 */
#include <iostream> using namespace std; const int N = 12; char a[N], b[N], s[N]; int main() { while (cin >> s) { int flag; for (int i = 0; i < 6; i++) a[i] = s[i]; for (int i = 0; i < 6; i++) b[i] = s[i + 6]; int i; for (i = 0; i < 3; i++) { flag = 0; for (int j = 0; j < 6; j++) { if (a[i] == b[j] && a[5 - i] == b[5 - j]) //每次检查到b的一对和a相同的正对面,必须将b中这两个位置清零,避免这对面再后面的循环中,再次被用到,使得多对一的错误情况仍被程序判对 { flag = 1; b[j] = b[5 - j] = 0; break; } } if (!flag) //如果没能在b中找到a中存在的一对面的颜色组合,则肯定是不同的正方体 break; } if (flag) cout << "TRUE" << endl; else cout << "FALSE" << endl; } return 0; }
/* 法三: 和法二有相似之处,都是用统计对面颜色组合的思想 不同的是,法三不像法二一样用循环枚举,而是直接保存在二维数组中,在检查对应数据是否一致 对于顺序,法三的处理方法是:对于每组对面,两种颜色先按原来的顺序累加一次,再交换顺序,再累加一次,这样就完全排除了顺序的影响 */
#include <iostream> #include <cstring> using namespace std; const int N = 130; const int M = 20; char a[N], b[N]; char s[M]; int cube1[N][N], cube2[N][N]; int main() { while (cin >> s) { memset(cube1, 0, sizeof (cube1)); memset(cube2, 0, sizeof (cube2)); for (int i = 0; i < 6; i++) a[i] = s[i]; a[6] = 0; for (int i = 0; i < 6; i++) b[i] = s[i + 6]; b[6] = 0; for (int i = 0; i < 3; i++) { cube1[a[i]][a[5 - i]]++; cube1[a[5 - i]][a[i]]++; cube2[b[i]][b[5 - i]]++; cube2[b[5 - i]][b[i]]++; } int i; for (i = 0; i < 3; i++) if (cube1[s[i]][s[5 - i]] != cube2[s[i]][s[5 - i]]) break; if (i == 3) cout << "TRUE" << endl; else cout << "FALSE" << endl; } return 0; }
/* 法四: 和法二法三的本质类似,是我当时看到那种思路时,就想到,可以把一对面的颜色作为一对pair,定义两个元素个数为3的pair数组,先通过初始化(将pair中较大的元素换为first)数组,消除位置的影响,再对pair排序,如果排序后,两个pair数组里,面的组合完全一致,说明是同样的正方体 */
#include <iostream> #include <algorithm> using namespace std; typedef pair<int, int> p; const int N = 12; char a[N], b[N], s[N]; p facea[3], faceb[3]; void solve() { for (int i = 0; i < 3; i++) //排序前作处理,使得面的颜色组合和顺序无关 { if (facea[i].first < facea[i].second) swap(facea[i].first , facea[i].second); if (faceb[i].first < faceb[i].second) swap(faceb[i].first , faceb[i].second); } sort(facea, facea + 3); sort(faceb, faceb + 3); for (int i = 0; i < 3; i++) if (facea[i] != faceb[i]) { cout << "FALSE" << endl; return; } cout << "TRUE" << endl; } int main() { while (cin >> s) { for (int i = 0; i < 6; i++) a[i] = s[i]; for (int i = 0; i < 6; i++) b[i] = s[i + 6]; for (int i = 0; i < 3; i++) { facea[i].first = a[i]; facea[i].second = a[5 - i]; faceb[i].first = b[i]; faceb[i].second = b[5 - i]; } solve(); } return 0; }