Java实现第八届蓝桥杯魔方状态
題目描述
二階魔方就是只有2層的魔方,只由8個(gè)小塊組成。
如圖p1.png所示。
小明很淘氣,他只喜歡3種顏色,所有把家里的二階魔方重新涂了顏色,如下:
前面:橙色
右面:綠色
上面:黃色
左面:綠色
下面:橙色
后面:黃色
請你計(jì)算一下,這樣的魔方被打亂后,一共有多少種不同的狀態(tài)。
如果兩個(gè)狀態(tài)經(jīng)過魔方的整體旋轉(zhuǎn)后,各個(gè)面的顏色都一致,則認(rèn)為是同一狀態(tài)。
請?zhí)峤槐硎緺顟B(tài)數(shù)的整數(shù),不要填寫任何多余內(nèi)容或說明文字。
開始拿到這道題沒什么思路,筆算算不來,模擬判重感覺太麻煩。大神說burnside引理可以做,學(xué)渣表示看不懂。。網(wǎng)上基本沒有求解的,有的也答案不一。最后還是模擬判重這么寫了。
我的答案:229878
測試:全同色魔方狀態(tài)為1,正確。正常二階魔方狀態(tài)3674160,正確。
思路:其實(shí)就是空間狀態(tài)搜索。模擬操作+判重。關(guān)于操作,二階魔方只做U(頂層順時(shí)針) R(右層順時(shí)針) F(前層順時(shí)針)就可以得到所有狀態(tài)了。判重需要旋轉(zhuǎn)整個(gè)魔方去比較。(判重小白現(xiàn)在只會(huì)用set)。
然后是,怎么去表示一個(gè)二階魔方。二階魔方8個(gè)塊,一個(gè)塊6面(看不見的作黑色考慮),所以我用了char st[8][7]去表示一個(gè)魔方。塊的順序如下:
上面的初始狀態(tài)表示就是{{“oybbgb”},{“oygbbb”},{“bygbby”},{“bybbgy”},{“obbogb”},{“obgobb”},{“bbgoby”},{“bbbogy”}}
o表示橙色,b表示黑色,g表示綠色,y表示黃色。
對于一個(gè)小塊,6個(gè)面的顏色定義順序如下:
所以,比如說,上面題目給的魔方,前面一層,左上角的橙黃綠塊,表示就是oybbgb
博主還是個(gè)小白,只能找來C++的代碼,還望 Java大佬及時(shí)寫出
#include <bits/stdc++.h> using namespace std; typedef char st[8][7]; st state[2000000]; set<string> all; st begin={{"oybbgb"},{"oygbbb"},{"bygbby"},{"bybbgy"},{"obbogb"},{"obgobb"},{"bbgoby"},{"bbbogy"}}; //st begin={{"oooooo"},{"oooooo"},{"oooooo"},{"oooooo"},{"oooooo"},{"oooooo"},{"oooooo"},{"oooooo"}}; //只有一個(gè)顏色的魔方 ans=1 //st begin={{"rykkbk"},{"rygkkk"},{"kygkko"},{"kykkbo"},{"rkkwbk"},{"rkgwkk"},{"kkgwko"},{"kkkwbo"}}; //正常2階魔方狀態(tài) r紅 y黃 b藍(lán) g綠 w白 o橙 k黑(紅對橙,白對黃,藍(lán)對綠,顏色相近的相對)這里白為底 前為紅 //需要將state大小改為4000000 //這個(gè)測試用例跑了20分鐘左右 560M內(nèi)存 ans=3674160 與實(shí)際二階魔方狀態(tài)數(shù)相同 見下截圖 int front, tail; void ucell(char *a){swap(a[0], a[2]); swap(a[2], a[5]); swap(a[5], a[4]);} void rcell(char *a){swap(a[1], a[0]); swap(a[0], a[3]); swap(a[3], a[5]);} void fcell(char *a){swap(a[2], a[1]); swap(a[1], a[4]); swap(a[4], a[3]);} void u(st &s)//頂層順時(shí)針旋轉(zhuǎn) {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 uwhole(st &s)//整個(gè)魔方從頂部看 順時(shí)針轉(zhuǎn) 用于判重 {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 f(st &s)//前面一層 順時(shí)針轉(zhuǎn) {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 fwhole(st &s)//整個(gè)魔方從前面看 順時(shí)針轉(zhuǎn) 用于判重 {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 r(st &s)//魔方右層順時(shí)針轉(zhuǎn) {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 rwhole(st &s)//整個(gè)魔方從右邊看 順時(shí)針轉(zhuǎn) 用于判重 {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]); } string convert(st &s)//魔方狀態(tài)二維字符數(shù)組 轉(zhuǎn)化為string {string ss;for(int i=0; i<8; i++)ss+=s[i];return ss; } bool try_to_insert(int tail)//判重 {st k;memcpy((void*)k, (void*)state[tail], sizeof(state[tail]));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.count(convert(k))==1){return false;}}}}all.insert(convert(k));return true; } int main() {front=0,tail=1;all.insert(convert(begin));memcpy((void*)state[0],(void*)begin,sizeof(begin));while(front!=tail){//對當(dāng)前狀態(tài)分別模擬三種操作U R F 然后判重 for(int i=0; i<3; i++){memcpy((void*)state[tail], (void*)state[front], sizeof(state[front]));if(i==0){u(state[tail]);if(try_to_insert(tail))tail++;}else if(i==1){r(state[tail]);if(try_to_insert(tail))tail++;}else if(i==2){f(state[tail]);if(try_to_insert(tail))tail++;}}front++;}cout<<front<<endl;return 0; } //ans 229878總結(jié)
以上是生活随笔為你收集整理的Java实现第八届蓝桥杯魔方状态的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 联想小新Air 13安装黑苹果兼macO
- 下一篇: 阶段01-html和css基础(总结04