0)
遍历所有点,求出连通块的数量,每到一块油田,就采用DFS或者BFS消除该油田以及附近连通的油田。
注意(易错):
①二维数组mat[i][j],i是第几行,j是第几列,所以搜到一点再搜该点周围八个方位(+dir[i][j])时,以及确定是否超出地图范围时,注意i是纵向加减,j是横向加减,且(0,0)原点在左上角,向右向下坐标的值都是不断递增。
②scanf("%c",&mat[i][j]); , scanf读入%c的字符时,会出错!可改成cin>>,或者scanf("%s",&mat[i]),如果数组第二维从1开始就scanf("%s",&mat[i]+1),scanf依然比cin快。(见如下BFS代码中的使用)
1)
DFS
#include <iostream> #include <stdio.h> #include <string.h> #include <queue> using namespace std; const int maxn=105; char mat[maxn][maxn]; int dir[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,1},{1,-1},{-1,-1}}; int m,n; int sum; void Dfs(int x,int y){ int tx; int ty; for(int i=0;i<8;i++){ tx=x+dir[i][0]; ty=y+dir[i][1]; if(1<=tx&&tx<=m&&1<=ty&&ty<=n){//注意!对于二维数组来说,x行y列,意味着x是纵向坐标,y是横向坐标 if(mat[tx][ty]=='@'){ mat[tx][ty]='*'; Dfs(tx,ty); } } } } int main() { while(scanf("%d%d",&m,&n)){ if(m==0&&n==0){ break; } //memset(mat,0,sizeof(mat)); sum=0; for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ //scanf("%s",mat[i]+1); cin>>mat[i][j]; //scanf("%c",&mat[i][j]); } } for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(mat[i][j]=='@'){ sum++; mat[i][j]='*'; Dfs(i,j); //深搜,消除同一连通块的所有油田标记 } } } cout<<sum<<endl; } return 0; }
#include <iostream> #include <stdio.h> #include <string.h> #include <queue> using namespace std; const int maxn=105; char mat[maxn][maxn]; int dir[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,1},{1,-1},{-1,-1}}; int m,n; int sum; struct Node{ int x; int y; }; void Bfs(int x,int y){ queue <Node> q; Node node; node.x=x; node.y=y; q.push(node); while(!q.empty()){ Node cur=q.front(); Node next; q.pop(); for(int i=0;i<8;i++){ next.x=cur.x+dir[i][0]; next.y=cur.y+dir[i][1]; if(mat[next.x][next.y]=='@'){ mat[next.x][next.y]='*'; q.push(next); } } } } int main() { while(scanf("%d %d",&m,&n)){ if(m==0&&n==0){ break; } memset(mat,0,sizeof(mat)); sum=0; int cur=1; for(int i=1;i<=m;i++){ //for(int j=1;j<=n;j++){ scanf("%s",mat[i]+1);//因为第二维也都是从1开始到n,所以+1开始 //cin>>mat[i][j]; //scanf("%c",&mat[i][j]); //} } for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(mat[i][j]=='@'){ sum++; mat[i][j]='*'; Bfs(i,j); //广搜,消除同一连通块的所有油田标记 } } } cout<<sum<<endl; } return 0; }
Description
Input
Output
Sample Input
1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0
Sample Output
0 1 2 2