POJ1753位壓縮BFS

來源:互聯網
上載者:User

在很多情況下,我們可以用一個整數或者多個整數把多變的狀態壓縮,這樣有利於空間上的最佳化,雖然在代碼量上並不能得到多少的好處,但是遇到資料量大的時候還是可以有一定的效果的。

以POJ1753為例,這題是推薦題中的簡單題了,一般的搜尋完全可以過,甚至不用搜尋。。。

我的方法是把BFS的狀態壓縮,由於每個牌面就4乘以4,也就是16個格子,每個格子只有黑白兩種狀態,用一個int型數就可以裝下整個狀態。

將牌面從上到下從左至右編號0到15,這樣int型數從低位開始的第i位標記為0或者1,分別表示白色和黑色,用位元運算進行狀態轉移。

看下我的結構體:

struct Node<br />{<br />int code;<br />int table;<br />int depth;<br />int last;<br />}start;

 

code表示這個狀態中各個格子是否被翻過,對應位如果為1,則表示被按過,這種題目有一個顯著的特點,那就是一個格子之多翻一次,否則和沒翻是一個效果,這樣我們記錄了格子後就可以知道哪些格子被我們翻過,那些沒有。

table表示狀態牌面的情況,第i位如果為1表示這位是黑色,否則為白色。

depth表示從初狀態到此狀態的步數。

last表示裝移到這個狀態翻轉的格子編號,這樣,我們每次都從最後一個翻轉的格子之後的格子開始搜尋,不會重複搜尋。

 

另外,位壓縮之後,寫一個狀態轉移函數hash(),用於轉移狀態。

int hash(int table,int op)<br />{<br />int st;</p><p>st=(1<<op);<br />if(op%4>0)<br />st|=(1<<(op-1));<br />if(op%4<3)<br />st|=(1<<(op+1));<br />if(op/4>0)<br />st|=(1<<(op-4));<br />if(op/4<3)<br />st|=(1<<(op+4));</p><p>return (table^st);<br />}

其中table參數就是需要變換的牌面,op代表翻轉的格子的編號,函數中的st變數表示需要翻轉的位,如果第i位需要翻轉,則這位就是1,否則為0,首先第op位一定是需要翻轉的,然後四個if判斷格子的位置,當格子在最左邊的時候,op%4等於0,最上邊的時候,op/4等於0,以此類推,當格子不是最左邊的時候,要對其左邊(op-1)位置的格子進行翻轉,因此更新st變數第(op-1)位為1,其他的類似。

 

在BFS函數中,末狀態就是15個0或者16個0((1<<16)-1),這樣直接用判斷整數是否相等就可以搞定。

 

主程式完整代碼如下:

#include <iostream><br />#include <cstring><br />#include <cstdlib><br />#include <cstdio><br />#include <queue></p><p>using namespace std;</p><p>struct Node<br />{<br />int code;<br />int table;<br />int depth;<br />int last;<br />}start;</p><p>int hash(int table,int op)<br />{<br />int st;</p><p>st=(1<<op);<br />if(op%4>0)<br />st|=(1<<(op-1));<br />if(op%4<3)<br />st|=(1<<(op+1));<br />if(op/4>0)<br />st|=(1<<(op-4));<br />if(op/4<3)<br />st|=(1<<(op+4));</p><p>return (table^st);<br />}</p><p>int bfs()<br />{<br />Node node,next;<br />queue<Node> q;</p><p>node.code=0;<br />node.table=start.table;<br />node.depth=0;<br />node.last=-1;<br />if(node.table==0||node.table==((1<<16)-1))<br />return 0;<br />q.push(node);<br />while(!q.empty())<br />{<br />node=q.front();<br />q.pop();<br />for(int i=node.last+1;i<16;i++)<br />{<br />if((node.code&(1<<i))==0)<br />{<br />next.code=(node.code|(1<<i));<br />next.table=hash(node.table,i);<br />next.depth=node.depth+1;<br />next.last=i;<br />if(next.table==0||next.table==((1<<16)-1))<br />return next.depth;<br />q.push(next);<br />}<br />}<br />}</p><p>return -1;<br />}</p><p>int main()<br />{<br />char str[10];</p><p>start.table=0;<br />for(int i=0;i<4;i++)<br />{<br />gets(str);<br />for(int j=0;j<4;j++)<br />{<br />if(str[j]=='b')<br />{<br />start.table|=(1<<(i*4+j));<br />}<br />}<br />}</p><p>int ret=bfs();<br />if(ret==-1)<br />printf("Impossible/n");<br />else<br />printf("%d/n",ret);</p><p>return 0;<br />}<br />

 

反思:這題BFS位壓縮其實還可以最佳化,code和last的作用是一樣的,因為每次都從最後翻轉的那位的後一位開始搜尋,不用判斷code變數,可以考慮將結構體變數再去掉一個。

 

聯繫我們

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