DFS,BFS回顧(各種題)(肺炎疫情中,祝平安)

2022-01-19 21:03:58 字數 3985 閱讀 4970

基礎知識:

入隊push()   //即插入元素

出隊pop()    //即刪除元素

front()        //讀取隊首元素

back()       //讀取隊尾元素

empty()     //判斷佇列是否為空

size()        //讀取佇列當前元素的個數         

poj 3278

乙個人在n點,牛在k點,這個人有兩種移動方式,+1,-1,*2;移一下就是一分鐘。問最短時間?

典型的bfs,,乙個發散式的搜尋,對於每個點,找出其可以到達的下三個點,第乙個到達k的,此為最快,輸出所需時間即可。

#include#include

#include

#include

const

int maxn = 1e5 +10

;int

st[maxn];

bool

vis[maxn];

using

namespace

std;

queue

q;void

first()

}int bfs(int n,int

k)

if(next==k)

return

st[next];}}

}int

main()

else

cout

}}

n-皇后問題,dfs解法:

acwing板子題位址

題中已經說的很清楚了,什麼叫n皇后。對於乙個棋子的擺放,我們應該保證這個棋子所在位置的一列,斜方向和反斜方向沒有棋子。怎麼判斷呢,我們引入bool型別的row陣列,row[i]=true,表明這一列已經放過棋子了,false表示沒有。這個row就解決了列問題,那麼斜方向問題怎麼解決呢?我們觀察一下,題中規定的斜方向,都是符合y=x+b/y=-x+b方程的。b=y-x/b=x+y。同乙個b,就是同一條斜線了。我的**中規定了d表示斜方向,ud表示反斜方向。比如!d[u+i],表示x=u,y=i這條斜線上沒有棋子,這個b=u+i之前沒有出現過。前面就說過,由於斜率一樣,所以只要保證這個b不一樣,所在斜線就不一樣。同理,反斜方向的也是一樣,用b=y-x來判斷,但是如果y-x<0的話,需要+n偏移一下,統一用ud[i-u+n]。

if(!row[i]&&!d[u+i]&&!ud[i-u+n])表示,對於x=u,y=i這個點,只要同一列,兩個斜線處均沒有棋子,就符合要求,放上一枚棋子。

其他的就是dfs的基本操作了,還原啦什麼的...

#include#include

#include

using

namespace

std;

const

int n = 27

;char

m[n][n];

bool

row[n],d[n],ud[n];

intn;

void

first()

void dfs(int

u) cout

; }

for(int i = 0 ; i < n ; i++)

}}int

main()

}

另一種比較原始的搜尋方式,比較慢:記錄皇后數目,如果==n的話,就輸出;

#include#include

#include

using

namespace

std;

const

int n = 27

;char

m[n][n];

bool

row[n],d[n],ud[n],urow[n];

intn;

void dfs(int x,int y,int

s)

if(x==n)

return

; }

if(!row[x]&&!urow[y]&&!d[x+y]&&!ud[y-x+n])

dfs(x,y+1

,s);

}int

main()

acwing 844.走迷宮:

走迷宮,從左上角走到右下角,0可走,1不可走,問最少需要幾步。

bfs解法:  通過g記錄地圖,d初始化為-1用來保證乙個點只能走一次以及記錄每個點到達終點的距離。

注意:使用以下語句來實現佇列記錄(x,y);

#includetypedef pair

pp;queueq;

q.push();

pp t=q.front;

那麼:t.first=1,t.second=2

**:

#include#include

#include

#include

using

namespace

std;

typedef pair

p; //

!!!const

int maxn = 105

;int

n,m;

intg[maxn][maxn];

int d[maxn][maxn]; //

每個點到起點的距離

//沒有走過

int dx=;

int dy=;

intbfs()

);

while(!q.empty()));}

}}

return d[n-1][m-1];}

intmain()

跟這個題基本一模一樣的:poj3984:

不同的是這個是要輸出路徑。我的做法是,pair乙個ing[x][y],ing[x][y].first,ing[x][y].second記錄x,y的前乙個點。因為是逆序,所以又存進乙個結構體裡,再逆序輸出,才變成正序了。

#include#include

#include

#include

using

namespace

std;

typedef pair

p; //

!!!const

int maxn = 105

;p ing[maxn][maxn];

intn,m;

intg[maxn][maxn];

int d[maxn][maxn]; //

每個點到起點的距離

//沒有走過

int dx=;

int dy=;

struct

node

st[maxn];

void

bfs()

);

while(!q.empty()));}

}}

return;}

intmain()

cout

<<"

(0, 0)

"=0;i--)

printf(

"(%d, %d)\n

",st[i].x,st[i].y);

return0;

}

經典油田問題:poj  2386  

dfs,碰到w,就變成『.』,再看八個方向,如果有w,就dfs。最後dfs的次數就是答案。

#include#include

#include

using

namespace

std;

const

int maxn = 200

;char

s[maxn][maxn];

intn,m;

void dfs(int x,int

y) }

}}int

main()

}cout

}

洛谷題集 01迷宮(dfs bfs)

有乙個僅由數字0與1組成的n n格迷宮。若你位於一格0上,那麼你可以移動到相鄰4格中的某一格1上,同樣若你位於一格1上,那麼你可以移動到相鄰4格中的某一格0上。你的任務是 對於給定的迷宮,詢問從某一格開始能移動到多少個格仔 包含自身 輸入格式 第1行為兩個正整數n,m。下面n行,每行n個字元,字元只...

ACM各種題集及各種總結大全

acm題集以及各種總結大全!雖然退役了,但是整理一下,供小弟小妹們以後切題方便一些,但由於近來考試太多,顧退役總結延遲一段時間再寫!先寫一下各種分類和題集,歡迎各位大牛路過指正。杭州電子科技大學 hdu acm題目 連線 關於acm的幫助 連線 北京大學 poj 題目 連線 浙江大學 zoj 題目 ...

回顧 做過的TRIE樹題

thusc2015 異或問題 standard io time limits 2000 ms memory limits 262144 kb detailed limits description 給定長度為n的數列x 和長度為m的數列y 令矩陣a中第i行第j列的值aij xi xor yj,每次詢...