2017/Province_Java_B/4/魔方状态
生活随笔
收集整理的這篇文章主要介紹了
2017/Province_Java_B/4/魔方状态
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目
二階魔方就是只有2層的魔方,只由8個小塊組成。
如圖p1.png所示。
小明很淘氣,他只喜歡3種顏色,所以把家里的二階魔方重新涂了顏色,如下:
前面:橙色
右面:綠色
上面:黃色
左面:綠色
下面:橙色
后面:黃色
請你計算一下,這樣的魔方被打亂后,一共有多少種不同的狀態。
如果兩個狀態經過魔方的整體旋轉后,各個面的顏色都一致,則認為是同一狀態。
請提交表示狀態數的整數,不要填寫任何多余內容或說明文字。
Ideas
“一共有多少種不同的狀態”,第一個想到DFS,然后想著想著,還找了個魔方研究,最后,QTMD,不做了。
實在搞不出來,C++參考大佬的模擬算法搞了一個出來。
2021-02-25更新
大神說burnside引理可以做,去研究研究。
https://blog.csdn.net/whereisherofrom/article/details/79631703
玩過魔方的都知道,上層有4種轉法(0、90、180、270),下層有4種轉法,前層有4種轉法,后層有4種轉法,左層有4種轉法,右層有4種轉法,所以一共有24種轉法,即一共擁有24個置換群,|G|=24。
二階魔方的8個角塊的位置可以進行任意交換,所以一共有8!種狀態。
通過兩個對立面的中心,分別旋轉90,180,270度,有3組面。
通過兩條對立的棱的中心,分別旋轉180度,有6組棱。
附大神手稿:
Code
C++
#include <vector> #include <set> #include <iostream>using namespace std; typedef char st[8][7]; st start = {{"oybbgb"},{"oygbbb"},{"bygbby"},{"bybbgy"},{"obbogb"},{"obgobb"},{"bbgoby"},{"bbbogy"}}; st q[4000000]; set<string> all_state; int ans, front, tail;string to_string(st &a) {string ans;for (int i = 0; i < 8; ++i) {ans += a[i];}return ans; }//上層的塊的旋轉,面的相對位置調換 void ucell(char *a) {swap(a[0], a[2]);swap(a[2], a[5]);swap(a[5], a[4]); }//上層順時針旋轉 void u(st &s) {ucell(s[0]);ucell(s[1]);ucell(s[2]);ucell(s[3]); // 塊的相對位置調換swap(s[1], s[0]);swap(s[2], s[1]);swap(s[3], s[2]);}//右層旋轉是面的位置變化 void rcell(char *a) {swap(a[1], a[0]);swap(a[0], a[3]);swap(a[3], a[5]); }void r(st &s)//魔方右層順時針轉 {rcell(s[1]);rcell(s[2]);rcell(s[6]);rcell(s[5]); // 塊的位置變化swap(s[2], s[1]);swap(s[5], s[1]);swap(s[6], s[5]); }void fcell(char *a) {swap(a[2], a[1]);swap(a[1], a[4]);swap(a[4], a[3]); }void f(st &s)//前面一層 順時針轉 {fcell(s[0]);fcell(s[1]);fcell(s[4]);fcell(s[5]);swap(s[1], s[5]);swap(s[0], s[1]);swap(s[4], s[0]); }void uwhole(st &s)//整個魔方從頂部看 順時針轉 用于判重 {u(s);//上層旋轉 // 下層旋轉ucell(s[4]);ucell(s[5]);ucell(s[6]);ucell(s[7]); // 完成自旋后,塊的位置變動swap(s[5], s[4]);swap(s[6], s[5]);swap(s[7], s[6]); }void fwhole(st &s)//整個魔方從前面看 順時針轉 用于判重 {f(s);fcell(s[2]);fcell(s[6]);fcell(s[7]);fcell(s[3]);swap(s[2], s[6]);swap(s[3], s[2]);swap(s[7], s[3]); }void rwhole(st &s)//整個魔方從右邊看 順時針轉 用于判重 {r(s);rcell(s[0]);rcell(s[3]);rcell(s[4]);rcell(s[7]);swap(s[3], s[7]);swap(s[0], s[3]);swap(s[4], s[0]); }bool try_insert(st &s) {st k;memcpy(k, s, sizeof(start));for (int i = 0; i < 4; i++) {fwhole(k);for (int j = 0; j < 4; j++) {uwhole(k);for (int q = 0; q < 4; q++) {rwhole(k);if (all_state.count(to_string(k)) == 1) {return false;}}}}all_state.insert(to_string(k));return true;}void solve() {front = 0;tail = 1;all_state.insert(to_string(start));memcpy(q[front], start, sizeof(start));//填充q[0],相當于第一個狀態入隊列while (front < tail) {/*將其所有變形,嘗試加入set中*/memcpy(q[tail], q[front], sizeof(start));//拷貝到tailu(q[tail]);//上層順時針旋轉if (try_insert(q[tail])) {tail++;//擴展隊列}memcpy(q[tail], q[front], sizeof(start));//拷貝到tailr(q[tail]);//右層順時針旋轉if (try_insert(q[tail])) {tail++;//擴展隊列}memcpy(q[tail], q[front], sizeof(start));//拷貝到tailf(q[tail]);//前順時針旋轉if (try_insert(q[tail])) {tail++;//擴展隊列}front++;//彈出隊首 // cout << front << " " << tail << endl;}cout << front << endl; }int main(int argc, const char *argv[]) {solve();return 0; }Python
from functools import reducedef f(n):return reduce(lambda x, y: x * y, range(1, n + 1))if __name__ == '__main__':s1 = f(8) * 3 ** 8 / 16s2 = 3 * f(4) * 3 ** 4s3 = 6 * f(4) * 3 ** 4print(((s1 + s2 + s3) // 24) // 3) 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的2017/Province_Java_B/4/魔方状态的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 征战蓝桥 —— 2017年第八届 ——
- 下一篇: 2017年第八届蓝桥杯 - 省赛 - C