HDU 3567 Eight II 打表,康托展開,bfs,g++提交可過c++不可過 難度:3

來源:互聯網
上載者:User

標籤:

http://acm.hdu.edu.cn/showproblem.php?pid=3567

相比Eight,似乎只是把目標狀態由確定的改成不確定的,但是康托展開+曼哈頓為h值的A*和IDA*都不過,而且也不好控制字典序

換個角度想,雖然起始狀態有很多,但是到底哪一位是1,哪一位是2不是最重要的,最重要的是和目標狀態對應,所以可以把起始狀態重新編碼為"12345678"這種形式(先不考慮X),然後目標狀態也對應過去,當考慮X的時候,我們可以認為起始狀態只有9種,分別是‘X‘在各個位置的情況

利用bfs可以得到每種起始狀態到對應的能夠達到的所有目標狀態的最短最小字典序轉移方法,如果對每個狀態都記錄一個字串肯定會MLE,所以只需要記錄上一個狀態到這一個狀態轉移所需要的操作即可

最後,對於每個目標狀態,逆向推出狀態轉移序列,然後逆著輸出即可

ps:一次處理3.6e6個狀態,如果不用queue或者迴圈數組會MLE,如果不用g++提交而用c++提交會TLE

 

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <cctype>using namespace std;const int base[9]={1,1,2,6,24,120,720,5040,40320};const int dx[4]={1,0,0,-1};/轉移方向,遵從字典序最小const int dy[4]={0,-1,1,0};const int maxh=362880;//每種開始狀態所對應狀態數int des;//用於儲存目標狀態hash值,判斷是否不需要轉移struct pnt{        int maz[3][3];        int ind;//標記起始狀態的編號        int x,y;        int hashCode;        pnt(){                x=y=hashCode=-1;        }        pnt(char * str){                for(int i=0;i<9;i++){                        if(str[i]==‘X‘){                                maz[i/3][i%3]=9;                                x=i/3;                                y=i%3;                                ind=i;                        }                        else maz[i/3][i%3]=str[i]-‘0‘;                }        }        int gethashcode(){                int ans=0;                for(int i=0;i<9;i++){                        int cnt=0;                        for(int j=0;j<i;j++){                                if(maz[j/3][j%3]>maz[i/3][i%3]){                                        cnt++;                                }                        }                        ans+=base[i]*cnt;                }                return hashCode=ind*maxh+ans;        }};bool in(int tx,int ty){        return tx>=0&&tx<3&&ty>=0&&ty<3;}int vis[maxh*10+1];//用於儲存某狀態是否已被遍曆,並儲存由何種操作得到該狀態int pre[maxh*10+1];//用於儲存某狀態由何種狀態轉移得到queue<pnt> que;char ans[maxh*10+1];//儲存答案的逆序char buff[300];//儲存輸入pnt s,e;int ind[10],indlen;//用於重新編碼bool input(){        if(scanf("%s",buff)!=1)return false;        indlen=0;//重新編碼        for(int i=0;i<9;i++){                if(buff[i]>=‘0‘&&buff[i]<=‘9‘){                        s.maz[i/3][i%3]=++indlen;                        ind[buff[i]-‘0‘]=indlen;                }                else{                        s.maz[i/3][i%3]=9;                        s.x=i/3;                        s.y=i%3;                        s.ind=i;                }        }        if(scanf("%s",buff)!=1)return false;        for(int i=0;i<9;i++){                if(buff[i]>=‘0‘&&buff[i]<=‘9‘){                        e.maz[i/3][i%3]=ind[buff[i]-‘0‘];                }                else{                        e.maz[i/3][i%3]=9;                        e.x=i/3;                        e.y=i%3;                }        }        e.ind=s.ind;//起始狀態相同        des=e.gethashcode();        return true;}void bfs(){        while(!que.empty()){                pnt tp=que.front();que.pop();                int x=tp.x,y=tp.y;                for(int i=0;i<4;i++){                        int tx=x+dx[i],ty=y+dy[i];                        if(in(tx,ty)){                                pnt nw=tp;                                swap(nw.maz[tx][ty],nw.maz[x][y]);                                nw.x=tx,nw.y=ty;                                if(vis[nw.gethashcode()]==-1){                                        vis[nw.hashCode]=i;                                        pre[nw.hashCode]=tp.gethashcode();                                        que.push(nw);                                }                        }                }        }}void init(){        memset(vis,-1,sizeof(vis));        memset(pre,-1,sizeof(pre));        pnt s1=pnt("12345678X");//9種起始狀態加入序列        vis[s1.gethashcode()]=-2;        que.push(s1);        pnt s2=pnt("1234567X8");        vis[s2.gethashcode()]=-2;        que.push(s2);        pnt s3=pnt("123456X78");        vis[s3.gethashcode()]=-2;        que.push(s3);        pnt s4=pnt("12345X678");        vis[s4.gethashcode()]=-2;        que.push(s4);        pnt s5=pnt("1234X5678");        vis[s5.gethashcode()]=-2;        que.push(s5);        pnt s6=pnt("123X45678");        vis[s6.gethashcode()]=-2;        que.push(s6);        pnt s7=pnt("12X345678");        vis[s7.gethashcode()]=-2;        que.push(s7);        pnt s8=pnt("1X2345678");        vis[s8.gethashcode()]=-2;        que.push(s8);        pnt s9=pnt("X12345678");        vis[s9.gethashcode()]=-2;        que.push(s9);        bfs();}int heap[maxh],sz;int getans(pnt e){//逆序遍曆        sz=0;        int last=e.gethashcode();        while(pre[last]>=0){                heap[sz++]=vis[last];                last=pre[last];        }        return sz;}void print(){        for(int i=sz-1;i>=0;i--){                switch(heap[i]){                case 0:                        putchar(‘d‘);break;                case 1:                        putchar(‘l‘);break;                case 2:                        putchar(‘r‘);break;                case 3:                        putchar(‘u‘);break;                }        }        putchar(‘\n‘);}int main(){        int T;        scanf("%d",&T);        init();        for(int ti=1;ti<=T;ti++){                input();                s.hashCode=s.gethashcode();                if(s.hashCode==des){                        printf("Case %d: 0\n",ti);                        puts("");                        continue;                }                vis[s.hashCode]=-2;                int step=getans(e);                printf("Case %d: %d\n",ti,step);                print();        }        return 0;}

  

HDU 3567 Eight II 打表,康托展開,bfs,g++提交可過c++不可過 難度:3

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.