列舉演算法思路訓練 poj1753

2021-10-08 02:45:45 字數 3156 閱讀 1483

從知乎找到乙份訓練大綱,先按照這個練習吧

poj1753

大意是4×4的棋盤上,不斷黑白面的翻**己和上下左右(如果有棋子的話),如果有可能翻到只有一種顏色,那麼算出來最少翻幾個棋子就可以做到只有一種顏色

列舉的思想是不斷地猜測,從可能的集合中一一嘗試,然後再判斷題目的條件是否成立。

oiwiki是這麼說的。。。。

不過「從可能的集合中一一嘗試」這段話引起了我的注意,原因後面再說

先說一下我的思路吧:

既然是4×4的棋盤,那麼翻棋子最多可能就是16個棋子每個棋子都翻一遍

因為乙個棋子翻兩遍等於沒翻

所以最初的想法就是直接把從乙個棋子不動到16個棋子都翻的情況乙個個看一遍

一共列出了2的16次方個可能性

(每個棋子有翻與不翻兩種狀態,一共16個棋子)

我用的方法是dfs

思路就是把每個座標翻轉與不翻轉兩個狀態都看一下,用遞迴建棧的方法從(0,0)到(4,4)不斷遞迴列舉,最後選出步數最少的情況

bool

dfs(

int n1,

int n2)

//順道一提,n1的if檢查一定放在n2前面if(

debug()

) a=1;

//第乙個點

point

(n1, n2)

;//按題目規律翻轉這個座標該翻轉的棋子

jud[n1]

[n2]

=true

;//標記已經選擇(已經翻了)

temp_min++

;//最小翻轉棋子數++

dfs(n1, n2 +1)

;//列數+1

//dfs(n1+1,n2);//加不加這個的區別看下面的

point

(n1, n2)

;//把這個坐邊翻回來

jud[n1]

[n2]

=false

;//不選,不翻這個棋子,翻其他的

temp_min--

;//最小翻轉棋子數--

dfs(n1, n2 +1)

;//dfs(n1+1,n2);

}

其實貌似可以先考慮不翻的情況,可以省一小部分操作的時間,算了就這樣吧

因為一開始我是考慮了搜尋下一列的同時搜尋下一行,所以做了重複的操作,兩個dfs變成了4個dfs

時間翻了4倍,所以留下乙個猜想,是不是複雜度和遞迴運算元稱n2^22

#include

using

namespace std;

char jud[6]

[6];

bool jud[6]

[6];

int min =

0x7fffffff

;int temp_min;

int a;

void

change

(int n1,

int n2)

void

point

(int n1,

int n2),,

,,};

for(

int i=

0;i<

5;i++)if

(jud[n1 + n[i][0

]][n2 + n[i][1

]])change

(n1 + n[i][0

], n2 + n[i][1

]);}

bool

isok()

return

true;}

bool

dfs(

int n1,

int n2)

//順道一提,n1的if檢查一定放在n2前面if(

debug()

) a=1;

//第乙個點

point

(n1, n2)

;//按題目規律翻轉這個座標該翻轉的棋子

jud[n1]

[n2]

=true

;//標記已經選擇(已經翻了)

temp_min++

;//最小翻轉棋子數++

dfs(n1, n2 +1)

;point

(n1, n2)

; jud[n1]

[n2]

=false

;//不選,不翻這個棋子,翻其他的

temp_min--

;//最小翻轉棋子數--

dfs(n1, n2 +1)

;}intmain()

getchar()

;}dfs(1,

1);if

(min ==

0x7fffffff

) cout <<

"impossible"

<< endl;

else cout << min << endl;

}

自己的思路做完搜了下別人的做法,這個比較好理解

就是說只關注第一行的四個棋子的各種情況,然後按照「如果上一行不是指定的顏色就翻轉」的思路,真就是看別人思路更醍醐灌頂

這也就是我為啥關注列舉演算法介紹裡面「集合」倆字的關注了

仔細想來,思考問題的方式不僅僅是從開始出發,可以直接關注結果然後從中找規律,比如說翻轉最多16次,還有「上一行不是我要的顏色下面就翻轉」的思路都是從結果倒退過來的..

....

....

....

閒扯一點廢話

我不知道以後的路子該怎麼走

我只知道

先讓自己開心再說

畢竟心態好才能做其他事

不想聽的就不聽

不想看的就不看

管他對與錯呢

對自己好點

才是實實在在的東西

有大破必有大立,

不要刻意去想以前混亂的訓練方法帶來的***了,

能記住的不會忘,

記不住的遲早學回來,

跑得快不一定贏,不跌跟頭才是勝利,

至少現在從地上爬起來了

加油!明天會更好!

poj1753 搜尋,列舉法

1 2014.3.1 2 poj175334 5 題意 6 給你乙個4 4的黑白棋盤,通過翻棋子使棋盤變為全白或全黑,7 以下 翻乙個位置 皆指翻著個位置和它周圍的四個棋子。8 翻子時四周的四個棋子如果存在的話顏色也會跟著改變。9 問最少需要多少步可以使棋盤變為一種顏色。10 11 思路 12 每一...

廣度搜尋 POJ 1753

題意 乙個4 4的棋盤,每個格仔放著乙個棋子。棋子一面是白色,一面是黑色。一次操作可以將某乙個格仔以及上下左右共5個格仔的棋子都翻過來,即白色變黑色,黑色變白色。現在給出一種棋盤狀態,問最少需要幾次操作可以將棋盤全部變為同種顏色。輸入 sample input bwwb bbwb bwwb bwww...

poj1753解題報告

1.演算法 核心是寬度優先搜尋和位處理。要找出最快的步數,用寬搜。1 寬度優先搜尋資料結構 佇列的單元unit包含x 用int的末16位記錄16個位置的資訊 rounds 記錄第幾輪達到當前的狀態 i 記錄該狀態是通過翻動哪個棋子得來的,以避免返回先前的狀態 queue是乙個佇列,記錄所有狀態 p,...