kuangbin帶你飛 專題一 簡單搜尋 (題解)
POJ 3279
題意:黑白的板,每次選擇一個十字形翻轉(十字板內黑白互換,若是邊界則不管),求最小將原圖變為全白的策略。
題解:列舉第一行翻轉情況(二進位制),2^c,然後驗證,由於第一行確定了,後面就可以跟著確定了。
儘量不要直接翻轉初始狀態,不然會影響後續的情況(我被坑了好幾個小時)。如下判斷:
int get(int x,int y)//(x,y)的顏色 { int res=map[x][y]; for(int i=0;i<5;i++) { int a=x+dx[i],b=y+dy[i]; if(a>=0&&a<m&&b>=0&&b<n) { res+=flip[a][b]; } } return res&1; }
POJ 1426
題意:找n的倍數,這個倍數的數字只有0或1;
題解:這個倍數有100位,每次餘數乘10之後+0或者+1,有兩種情況,可以用BFS做。
用三維陣列pre[][][]存狀態,第一維是餘數,第二維是此時的位數,第三維是當前位是0還是1,pre的值為前一個狀態
void dabiao(){ for(int n=1;n<=200;n++){ memset(pre,-1,sizeof(pre)); queue<int> q; int m=1%n; pre[m][1][1]=-1; q.push(m*10000+10+1); while(!q.empty()){ int t=q.front(); int x=t/10000; int y=(t-10000*x)/10; int z=t-10000*x-10*y; q.pop(); if(x==0){ cun(t,n); break; } for(int i=0;i<2;i++){ m=(x*10+i)%n; pre[m][y+1][i]=t; q.push(m*10000+(y+1)*10+i); } } } }
POJ 3414 pots
這個題應該比較明顯是BFS,不過狀態記錄有點煩, 我開了int pre[105][105][5][30] 這樣的四位陣列記錄狀態。。。
FZU 2150
比較繁瑣的BFS,wa了好多次沒有發現錯誤。
題意 :就是有兩個熊孩子要把一個正方形上的草都給燒掉,他倆同時放火燒,燒第一塊的時候是不花時間的,每一塊著火的都可以在下一秒燒向上下左右四塊#代表草地,.代表著不能燒的。問你最少花多少時間可以燒掉,如果燒不掉就輸出-1
思路 :先BFS判斷有幾個連通塊,大於2輸出-1,等於2時,就分別求出兩個連通塊裡的最短時間然後取最大,等於1時,就遍歷在一個連通塊裡任意兩個點(可以相同)都放進佇列裡BFS(寫的時候失誤太多)
UVa 11642
真是題題trick,此題不造我哪裡錯了,無法理解,題解是火和人一起放進queue裡,然後火先走,人走出去的時候就是可以
HDU 1495
這題的題意就是個大坑。題目是非常的簡單
trick: 題目中只說要平分可樂,但實際上本題對於最終實現平分的方式也是有要求的,那就是最終在S中必須有S/2單位的可樂,且過程中不能提前喝可樂。
例如 4 1 3 這組資料,只要從4倒到3,再從3倒到1,一共倒2次就能夠得到2單位的可樂了(存放在M中),但樣例中給的答案是倒3次,也就是要把N中那1單位的可樂倒回S中才行。 再比如 6 1 1 這組資料,其實我可以每次從S(S=6)中倒出1單位的可樂到N或M中,再把它喝掉,如此迴圈3次就可以實現平分可樂,但這種平分的方式也不被本題所允許。