ZOJ 3736 Pocket Cube 腦補+BFS
阿新 • • 發佈:2019-02-19
2*2*2的魔方,給出初始狀態和最大步數N,問在旋轉不超過N次的情況下,最多能還原魔方的幾個面。
這題的關鍵是腦補出魔方六種操作的方案...最好的辦法是把題上的圖抄下來,做成一個正方體....然後就各種輕鬆加愉快了....由於最大的步數僅僅是7,狀態的判重都不用寫了,每生成一個狀態算一下有幾個面是ok的,更新一下最大值就ok了...
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <queue> #include <stack> #include <map> using namespace std; typedef long long ll; int n,m; int num; const int ff[6][24]={ {0,21,2,23,4,5,6,1,9,15,10,11,12,3,8,14,16,7,18,13,20,17,22,19}, {0,7,2,13,4,5,6,17,14,8,10,11,12,19,15,9,16,21,18,23,20,1,22,3}, {2,0,3,1,6,7,8,9,23,22,10,11,12,13,14,15,16,17,18,19,20,21,5,4}, {1,3,0,2,23,22,4,5,6,7,10,11,12,13,14,15,16,17,18,19,20,21,9,8}, {0,1,11,5,4,16,12,6,2,9,10,17,13,7,3,15,14,8,18,19,20,21,22,23}, {0,1,8,14,4,3,7,13,17,9,10,2,6,12,16,15,5,11,18,19,20,21,22,23} }; struct tube { int d[24]; int cnt; tube(){} // bool operator<(const tube& kk)const // { // for (int i=0; i<24; i++) // if (d[i]!=kk.d[i]) return d[i]<kk.d[i]; // } // bool operator==(const tube& kk)const // { // bool res=true; // for (int i=0; i<24; i++) // if (d[i]!=kk.d[i]) // { // res=false; // break; // } // return res; // } // bool operator>(const tube& kk)const // { // for (int i=0; i<24; i++) // if (d[i]!=kk.d[i]) return d[i]>kk.d[i]; // } }; tube st; tube trans(tube tmp,int k) { tube res; for (int i=0; i<24; i++) res.d[i]=tmp.d[ff[k][i]]; return res; } int count(tube tmp) { int res=0; if (tmp.d[0]==tmp.d[1] && tmp.d[1]==tmp.d[2] && tmp.d[2]==tmp.d[3]) res++; if (tmp.d[8]==tmp.d[9] && tmp.d[14]==tmp.d[15] && tmp.d[8]==tmp.d[14]) res++; if (tmp.d[6]==tmp.d[7] && tmp.d[7]==tmp.d[12] && tmp.d[12]==tmp.d[13]) res++; if (tmp.d[4]==tmp.d[5] && tmp.d[5]==tmp.d[11] && tmp.d[11]==tmp.d[10]) res++; if (tmp.d[16]==tmp.d[17] && tmp.d[17]==tmp.d[19] && tmp.d[19]==tmp.d[18]) res++; if (tmp.d[20]==tmp.d[21] && tmp.d[21]==tmp.d[22] && tmp.d[22]==tmp.d[23]) res++; return res; } int ans; void bfs() { queue<tube> q; q.push(st); // map<tube,int> mp; // mp[st]=1; ans=count(st); while(!q.empty()) { tube now=q.front(); q.pop(); tube tmp; for (int i=0; i<6; i++) { tmp=trans(now,i); tmp.cnt=now.cnt+1; // if (mp.find(tmp)!=mp.end()) // { // mp[tmp]=1; // ans=max(ans,count(tmp)); // if (tmp.cnt<num) q.push(tmp); // } ans=max(ans,count(tmp)); if (tmp.cnt<num) q.push(tmp); } } } int main() { // freopen("in.txt","r",stdin); while(cin>>num) { for (int i=0; i<24; i++) { cin>>st.d[i]; } st.cnt=0; bfs(); cout<<ans<<endl; } return 0; }