程式設計訓練(三)

2021-08-30 15:12:08 字數 3279 閱讀 5684

關於深度優先演算法(dfs)和廣度優先演算法(bfs)的一點東西。

深度優先,本質應該是圖的遍歷,從某個頂點出發,訪問圖中的每乙個頂點,而深度優先就意味著它是優先選擇更深層次的頂點,用樹來看得的話,那就是最快到達某個葉子結點。

一般步驟:

1)選取圖中某一頂點vi為出發點,訪問並標記該頂點;

2)以vi為當前頂點,依次搜尋vi的每個鄰接點vj,若vj未被訪問過,則訪問和標記鄰接點vj,若vj已被訪問過,則搜尋vi的下乙個鄰接點;

3)以vj為當前頂點,重複步驟2),直到圖中和vi有路徑相通的頂點都被訪問為止;

4)若圖中尚有頂點未被訪問過(非連通的情況下),則可任取圖中的乙個未被訪問的頂點作為出發點,重複上述過程,直至圖中所有頂點都被訪問。

通俗來講,深度優先就像是地下尋寶,好東西都在地下深處,我們要一直往下挖,差不多就留個標記,不能往下挖了,我們就往前後左右挖,然後再試著往下挖,都不行的話,我們就往上爬回去一點,再往前後左右挖,直到去過所有能去的地方,回到地面上。

我們來看乙個圖

我們按照深度優先來排列這個無向圖的拓撲序列,其中字母按abcdefg順序儲存。從標記頂點a並從它出發,訪問a的鄰接點c、d、f,在同深度的情況下,按照儲存順序優先選擇c並標記;然後繼續訪問c的鄰接點b、d,這裡優先選b並標記;在b無鄰接點的情況下回退乙個節點,接著訪問c的另乙個鄰接點d並標記;一直回退到a,因為d已經被標記,所以選擇a的最後乙個鄰接點f,按照之前的步驟訪問,最後得到的序列為:a -> c -> b -> d -> f -> g -> e

單詞接龍

單詞接龍是乙個與我們經常玩的成語接龍相類似的遊戲,現在我們已知一組單詞,且給定乙個開頭的字母,要求出以這個字母開頭的最長的「龍」(每個單詞都最多在「龍」中出現兩次),在兩個單詞相連時,其重合部分合為一部分,例如 beast和astonish,如果接成一條龍則變為beastonish,另外相鄰的兩部分不能存在包含關係,例如at 和 atide 間不能相連。

輸入輸出格式

輸入格式:

輸入的第一行為乙個單獨的整數n (n≤20)表示單詞數,以下n每行有乙個單詞,輸入的最後一行為乙個單個字元,表示「龍」開頭的字母。你可以假定以此字母開頭的「龍」一定存在.

輸出格式:

只需輸出以此字母開頭的最長的「龍」的長度

看**

#include#include#define maxsize 30

using namespace std;

int n,maxlength;

int repeat[maxsize][maxsize],visit[maxsize];

string words[maxsize];

//預處理,把重複長度存到repeat

void pre(string a,string b,int x,int y)

}else }}

}}void dfs(int pos,int sum)

}}int main()

cin>>ch;

for(i = 1;i <= n;i++)

}

for(i = 1;i <= n;i++)

}cout<1、從圖中某個頂點v0出發,並訪問此頂點;

2、從v0出發,訪問v0的各個未曾訪問的鄰接點w1,w2,…,wk;然後,依次從w1,w2,…,wk出發訪問各自未被訪問的鄰接點;

3、重複步驟2,直到全部頂點都被訪問為止。

舉個通俗的例子,廣度優先遍歷就是魔塔遊戲,你要先把這一層裡的每乙個位置的怪物都打死(相當於留下標記),然後才能拿到鑰匙去到下一層。

再看剛剛那個圖

我們可以先給這個圖簡單的分一下層:

然後讓我們來遍歷它。

先訪問根結點a並標記,然後按字典順序依次訪問第二層的c、d、f,並標記;接著訪問第三層的b、g,標記;最後一層的e,標記;最後的拓撲序列就是:a -> c -> d -> f -> b -> g -> e

01迷宮

有乙個僅由數字0與1組成的n×n格迷宮。若你位於一格0上,那麼你可以移動到相鄰4格中的某一格1上,同樣若你位於一格1上,那麼你可以移動到相鄰4格中的某一格0上。

你的任務是:對於給定的迷宮,詢問從某一格開始能移動到多少個格仔(包含自身)。

輸入輸出格式

輸入格式:

第1行為兩個正整數n,m;

下面n行,每行n個字元,字元只可能是0或者1,字元之間沒有空格;

接下來m行,每行2個用空格分隔的正整數i,j對應了迷宮中第i行第j列的乙個格仔,詢問從這一格開始能移動到多少格。

輸出格式:

m行,對應每個詢問輸出相應答案。

來看**

#include#include#define maxsize 1000001

#define size 1001

using namespace std;

int father[maxsize],child[maxsize]; //fa為根,ch為子節點

int n;

int u[4] = ;

int v[4] = ; //四個方向

char s[size][size]; //存迷宮

//查int find(int x)

//並void union_(int x,int y)

}//構造點到節點一一對映:(i,j)=i*n+j;

int dfs(int x,int y)

father[x*n+y] = x*n+y,child[x*n+y] = 1; //構造對映

for(int k = 0;k < 4;k++)

}return find(x*n+y);

}int main()

for(int k = 0;k < m;k++){

cout這裡用到了乙個概念叫做並查集,關於這個有篇比較好的文章,供以參考:

那麼這次總結就到這裡啦,題目**洛谷,再貼波github

以上!

程式設計訓練 金幣

國王為他的忠誠的騎士支付金幣。在他服役的第一天,騎士收到一枚金幣。在接下來2天 第二天和第三天的服務 騎士每天收到2金幣。在未來三天 第五,第四,和第六天的服務 騎士每天收到三金幣。在未來四天 第七,第八,第九,和第十天的服務 騎士每天收到四金幣。這一模式的付款方式將繼續下去 在接下來的n天騎士每天...

程式設計訓練 打牌

牌只有1到9,手裡拿著已經排好序的牌a,對方出牌b,用程式判斷手中牌是否能夠壓過對方出牌。規則 出牌牌型有5種 1 一張 如4 則5 9可壓過 2 兩張 如44 則55,66,77,99可壓過 3 三張 如444 規則如 2 4 四張 如4444 規則如 2 5 五張 牌型只有12345 23456...

程式設計訓練 棋盤

棋盤是指乙個行和列編號從1 n的nxn的二進位制矩陣,當行號和列號之和為偶數時該矩陣對應位置為黑色的 1 否則為白色的 0 以下圖示為n 1 2 3時的棋盤。給出乙個nxn的二進位制矩陣,請找出位於該矩陣內的最大尺寸的完整棋盤,以及最大尺寸棋盤的數量 棋盤可以交疊 每個測試用例的第一行是乙個正整數n...