從知乎找到乙份訓練大綱,先按照這個練習吧
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,...