POJ 2965 The Pilots Brothers’ refrigerator

來源:互聯網
上載者:User

這題與1753點燈遊戲很類似,只不過變換狀態的方式不一樣罷了..

狀態壓縮+BFS就可以解決,與1753不同的就是要記錄路徑,可以通過給隊列中的元素加上pre和next屬性來實現.

已耗用時間690MS,感覺挺慢的,後來在dicuss裡看到了一位大牛的總結,很好的方法啊..有時候做題前多思考真的是很重要啊,即使是對一些很面熟的題目.

“先看一個簡單的問題,如何把'+'變成'-'而不改變其他位置上的狀態?答案是將該位置(i,j)及位置所在的行(i)和列(j)上所有的handle更新一次,結果該位置被更新了7次,相應行(i)和列(j)的handle被更新了6次,剩下的被更新了4次.被更新偶數次的handle不會造成最終狀態的改變.因此得出高效解法,在每次輸入碰到'+'的時候,自增該位置與相應的行和列,當輸入結束後,遍曆數組,所有為奇數的位置則是操作的位置,而奇數位置的個數之和則是最終的操作次數.”,

#include <cstdio>#include <string.h>using namespace std;struct record{int va,pre,next,c;//分別記錄目前狀態,前驅,後繼,和操作 }r[70000]; int vi[70000];//是否訪問 int st;//起始狀態 int f(int x,int i){//位元運算更改狀態 x^=1<<i;//更改當前格 int lx=i/4,ly=i%4; //擷取行,列 for(int j=0;j<4;j++){x^=1<<(4*j+ly);//更改列 x^=1<<(4*lx+j);//更改行 }return x;}void solve(int pos){int a,b,res=1;int head=pos;while(r[head].pre!=0){//根據前驅向前找直到起始點, 記錄變換次數和後驅 r[r[head].pre].next=head;head=r[head].pre;res++;}printf("%d\n",res);for(int i=0;i<res;i++){//根據後驅和變換次數進行輸出printf("%d %d\n",r[head].c/4+1,r[head].c%4+1);head=r[head].next;}}void bfs(int x){if(x==0)return;int front=0,tail=0;r[0].va=x;vi[x]=1;tail++;while(1){int v=r[front].va;for(int i=0;i<16;i++){int ns=f(v,i);if(vi[ns]==0){r[tail].va=ns;r[tail].pre=front;r[tail].c=i;if(ns==0){//找到結果 solve(tail);return; }vi[ns]=1;tail++;}}front++;}}int main(){char line[6];st=0;for(int i=0;i<4;i++){scanf("%s",line);for(int j=0;j<4;j++){if(line[j]=='+')st+=1<<(4*i+j);}}memset(vi,0,sizeof vi);bfs(st);return 0;} 

聯繫我們

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