洛谷P1451 求細胞數量
阿新 • • 發佈:2022-03-19
題目連結:https://www.luogu.com.cn/problem/P1451
開始的時候想麻煩了,經過一次次的調不過終於成功了;
本題其實是一道很中規中矩的搜尋題,但是一些細節方面需要注意,並且值得注意的是,標記陣列vis是不用回溯的,因為一部分元素||字元只能算一次,所以說就免去回溯了;
程式碼及其思路如下:(dfs)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m; 4 bool vis[110][110]; 5 char ch[110][110]; 6 int ans; 7 int dir[4][2]={ 8 {-1,0}, 9 {0,-1}, 10 {1,0}, 11 {0,1} 12 }; 13 void dfs(int x,int y) 14 { 15 vis[x][y]=true;//走過的元素標記 16 for(register int i=0;i<4;i++) 17 { 18 int newx=x+dir[i][0]; 19 int newy=y+dir[i][1]; 20 if(newx<=0||newx>n||newy<=0||newy>m||vis[newx][newy]||ch[newx][newy]=='0')//如果下一個元素不滿足條件就跳過 21 continue; 22 dfs(newx,newy);//vis不必回溯因為一部分元素算一次就可以了 23 } 24 } 25 int main() 26 { 27 ios::sync_with_stdio(false); 28 cin>>n>>m; 29 for(register int i=1;i<=n;i++) 30 { 31 for(register int j=1;j<=m;j++) 32 { 33 cin>>ch[i][j];34 } 35 } 36 for(register int i=1;i<=n;i++) 37 { 38 for(register int j=1;j<=m;j++) 39 { 40 if(ch[i][j]!='0'&&!vis[i][j])//注意是字串並且要走沒走過的 41 { 42 dfs(i,j); 43 ans++; 44 } 45 } 46 } 47 cout<<ans<<endl; 48 return 0; 49 }
下面提供bfs思路:
1 #include<bits/stdc++.h> 2 using namespace std; 3 struct node 4 { 5 int x,y; 6 }; 7 int n,m,ans=0;//n行m列,ans為答案 8 int a[105][105];//存矩陣 9 bool used[105][105];//記錄是否走過 10 int dx[4]={-1,1,0,0};//向上下左右走一步行號和列好的改變 11 int dy[4]={0,0,-1,1}; 12 void bfs(int x,int y)//bfs 13 { 14 queue<node>q; 15 used[x][y]=true; 16 node st,nxt; 17 st.x=x; 18 st.y=y; 19 q.push(st); 20 while(!q.empty()) 21 { 22 st=q.front(); 23 q.pop(); 24 for(int i=0;i<4;i++) 25 { 26 nxt.x=st.x+dx[i]; 27 nxt.y=st.y+dy[i]; 28 if(a[nxt.x][nxt.y]==0 || used[nxt.x][nxt.y]==true) 29 continue; 30 used[nxt.x][nxt.y]=true;//把這一連通塊的點染色 31 q.push(nxt); 32 } 33 34 } 35 } 36 int main() 37 { 38 cin>>n>>m; 39 memset(a,0,sizeof(a)); 40 for(int i=1;i<=n;i++) 41 for(int j=1;j<=m;j++) 42 scanf("%1d",&a[i][j]); 43 for(int i=1;i<=n;i++) 44 { 45 for(int j=1;j<=m;j++) 46 { 47 if(!used[i][j]&&a[i][j]!=0) 48 { 49 bfs(i,j); 50 ans++;//若這一連通塊沒搜過ans++ 51 } 52 } 53 } 54 cout<<ans; 55 return 0; 56 }