ZOJ 3736 Pocket Cube 脑补+BFS

来源:互联网 发布:mysql my.cnf 编辑:程序博客网 时间:2024/05/01 10:30

       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;}