P4289 [HAOI2008]移動玩具

來源:互聯網
上載者:User

標籤:empty   printf   條件   style   tar   ret   include   移動   check   

P4289 [HAOI2008]移動玩具

雙向bfs+狀態壓縮+記憶化搜尋

雙向bfs用於對bfs的最佳化,每次找到可擴充節點少的一邊進行一次bfs,找到的第一個互相接觸的點即為最短路徑

矩陣範圍僅4*4大小,我們容易想到用位元壓縮其狀態,利於求解。

既然轉成二進位,大小又<2^17,那麼可以再加數組進行記憶化

不要忘了起點終點相同時的特判qwq

#include<iostream>#include<cstdio>#include<queue>#include<cstring>using namespace std;struct data{int zip,step;};int ans,rec1[65538],rec2[65538]; //rec:記憶化用queue <data> h[2]; //分別代表從起點/終點開始的bfs隊列inline void check(int to,int p,data x){ //檢查該點是否符合條件    if(rec1[to]!=-1){         if(rec2[to]!=p) ans=rec1[to]+x.step+1; //如果該點已被對面搜到,那麼已經得出最優解    }else{        rec1[to]=x.step+1,rec2[to]=p;        h[p].push((data){to,x.step+1});    }}void output(int t){ //檢查用,將10進位數轉回4*4的二進位矩陣    cout<<"---\n";    int h[19];    for(int k=t,i=15;i>=0;--i) h[i]=k&1,k>>=1;    for(int i=0;i<4;++i){            for(int j=i*4;j<=i*4+3;++j) cout<<h[j];            cout<<endl;        }    cout<<"---\n";}inline void bfs(){    int p=(h[0].size()>h[1].size()),now=(h[p].front()).step; //找到可擴充節點少的一邊,並且只擴充一層    while(!h[p].empty()){        data x=h[p].front();        if(x.step!=now||ans) break;        h[p].pop();        int k=1,to;        for(int i=1;i<65536;i<<=1,++k){ //用位元表示轉移過程            if(!(x.zip&i)) continue;            if(k%4!=0&&(!(x.zip&(i<<1)))){ //向左                to=x.zip-i+(i<<1);                check(to,p,x);            }            if(k%4!=1&&(!(x.zip&(i>>1)))){ //向右                to=x.zip-i+(i>>1);                check(to,p,x);            }            if(k>4&&(!(x.zip&(i>>4)))){ //向下                to=x.zip-i+(i>>4);                check(to,p,x);            }            if(k<13&&(!(x.zip&(i<<4)))){ //向上                to=x.zip-i+(i<<4);                check(to,p,x);            }        }    }}int main(){    memset(rec1,-1,sizeof(rec1));    char q[6]; int tot1=0,tot2=0;    for(int i=1;i<=4;++i){  //矩陣轉成十進位數        cin>>q;        for(int j=0;j<=3;++j) tot1+=q[j]-48,tot1<<=1;     }tot1>>=1; //注意最後要右移一位    h[0].push((data){tot1,0}); rec1[tot1]=0; rec2[tot1]=0;    for(int i=1;i<=4;++i){        cin>>q;        for(int j=0;j<=3;++j) tot2+=q[j]-48,tot2<<=1;     }tot2>>=1;    h[1].push((data){tot2,0}); rec1[tot2]=0; rec2[tot2]=1;    while(!ans&&tot1!=tot2) bfs(); //注意特判    printf("%d",ans);    return 0;}

 

P4289 [HAOI2008]移動玩具

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.