hdu----(1528)Card Game Cheater(最大匹配/貪心)
阿新 • • 發佈:2022-05-05
P1596 [USACO10OCT]Lake Counting S
洛谷題
這是一道DFS ( Depth First Search 深度優先搜尋) 的題目
啥是DFS?
DFS就是從起點開始搜尋,當碰到岔道口時,總是選擇一條路前進。知道無路可走,才返回到離自己最近的沒被訪問過的岔道口繼續前進。
舉個栗子:
我們有一棵樹
我們從根節點A開始搜尋,第一步走到B節點,發現可以繼續走,便走到D節點,發現又可以繼續走,就來到了H節點。
到了H節點之後,發現無路可走,便退回到D節點,向I節點方向走。直到H I J三個節點都被訪問過,於是再退回到B節點開始向E節點方向搜尋......
直到找到終點 ,搜尋結束。
將此過程記錄下來,如下:
A->B
B->D
D->H
D->I
D->J
B->E
......
C->F
C->G
我們將這一不撞南牆不回頭過程叫做DFS(Depth First Search深度優先搜尋),簡稱深搜。
現在來看題目:
題目要求我們找水坑的數量
對於每一個水坑,我們都可以用DFS來遍歷一遍,並作為已訪問。
DFS函式思路:
1 void dfs(int x,int y){
2 //將該座標標記為已訪問
3 //判斷該點周圍8個方向是否有水窪
4 //如果有繼續搜尋下一個點
5 }
如何判斷該點周圍8個方向是否有水窪呢?
這個時候我們就需要請我們的老朋友:方向陣列來幫忙
方向陣列就是用陣列記錄新座標與當前座標的關係的陣列(如下圖)
該題的方向陣列長這樣:
int dx[]={0,0,1,-1,-1,1,-1,1};
int dy[]={1,-1,0,0,1,1,-1,-1};
整個程式碼思路:
1 //標頭檔案、巨集定義
2 using namespace std;
3 //定義田地長寬、田地、方向陣列、計數器
4 void dfs(int x,int y){
5 //將該座標標記為已訪問
6 //判斷該點周圍8個方向是否有水窪
7 //如果有繼續搜尋下一個點
8 }
9 int main(){
10 //初始化田地
11 //輸入
12 //遍歷整個田地
13 /*
14 如果當前座標為水窪
15 計數器++
16 從當前點開始搜尋 標記水窪
17 */
18 //輸出
19 return 0;
20 }
理解思路後,便可以著手寫程式碼:
AC Code:
1 #include<bits/stdc++.h>//萬能頭美滋滋
2 #define ll long long
3 using namespace std;
4 int n,m;
5 int cnt=0;
6 char g[122][122];
7 int dx[]={0,0,1,-1,-1,1,-1,1};//方向陣列
8 int dy[]={1,-1,0,0,1,1,-1,-1};
9 void dfs(int x,int y){
10 g[x][y]='.';//將水窪標記為旱地後,不會被再次訪問
11 for(int i=0;i<8;i++){
12 if(g[x+dx[i]][y+dy[i]]!='.') dfs(x+dx[i],y+dy[i]);
13 }
14 }
15 int main(){
16 cin>>n>>m;
17 memset(g,'.',sizeof g);//將田地初始化為'.'需要cstring標頭檔案
18 for(int i=1;i<=n;i++){
19 for(int j=1;j<=m;j++){
20 char c;
21 cin>>c;
22 g[i][j]=c;
23 }
24 }
25 for(int i=1;i<=n;i++){
26 for(int j=1;j<=m;j++){
27 if(g[i][j]!='.'){//旱地不需要被搜尋
28 cnt++;
29 dfs(i,j);
30 }
31 }
32 }
33 cout<<cnt;
34 return 0;
35 }
感謝瀏覽!
祝所有的母親母親節快樂!