3 条题解
-
6
!用了深度优先搜索算法
#include<bits/stdc++.h> using namespace std; // dx[i]与dy[i]是方格的移动 short n,m,ans,dx[4]={-1,0,0,1},dy[4]={0,-1,1,0}; // 因为方格中只有0和1,所以我开的是bool数组;vis数组记录方格中的点是否访问过 bool block[105][105],vis[105][105]; void dfs(short x,short y){ for(short i=0;i<4;i++){ // 在某个点往四个方向搜寻 short nx=x+dx[i],ny=y+dy[i]; // 走一步后的新的点(nx,ny) if(block[nx][ny]&&vis[nx][ny]==false){ // 方格的点为1且未访问 vis[nx][ny]=true; // 标记为已访问 dfs(nx,ny); // 从新点开始继续搜索 } } return; // 所有深搜完成后代表找到了1个连通块 } int main(){ ios::sync_with_stdio(false); // 输入输出加速 cin.tie(0); cout.tie(0); cin>>n>>m; for(short i=1;i<=n;i++) for(short j=1;j<=m;j++) cin>>block[i][j]; for(short i=1;i<=n;i++){ // 遍历方格 for(short j=1;j<=m;j++){ if(block[i][j]&&vis[i][j]==false){ // 方格的点为1且未访问 vis[i][j]=1; // 标记为已访问 ans++; // 一次深搜找的是一个连通块,所以ans直接加1 dfs(i,j); } } } cout<<ans; return 0; }
-
0
这道题第一眼眼晕,其实就是变相的dfs 第一次做的时候,想到了要用dfs,结果脑子抽了,从(1,1)开始搜索,这就会导致无法判断指针坐标是否走出连通块 后来看了大佬的题解,才豁然开朗,茅塞顿开。 **代码注释如下(已AC,请放心食用):**
#include <iostream> using namespace std; int n,m,cnt=0; bool book[101][101];//这里我做了优化,visited和book数组合一:book[i][j]=false要么是本来就是0,这下不会访问;要么代表已访问,不会二次访问,称其为“染色思想”,之前学校做一个C++卷子做到了,所以知道要dfs,还可以染色 void dfs(int x,int y){ if(x<n&&book[x+1][y]){dfs(x+1,y);book[x+1][y]=false;}//向右 if(x>1&&book[x-1][y]){dfs(x-1,y);book[x-1][y]=false;}//向左 if(y<m&&book[x][y+1]){dfs(x,y+1);book[x][y+1]=false;}//向下 if(y>1&&book[x][y-1]){dfs(x,y-1);book[x][y-1]=false;}//向上 } int main(){ ios::sync_with_stdio(false); cin.tie(NULL),cout.tie(NULL);//输入输出加速器 cin>>n>>m; for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>book[i][j]; for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){if(book[i][j]){book[i][j]=false;dfs(i,j);cnt++;}}//从一个没访问过的源点开始访问,也就是连通块的最左上坐标;搜完了也就说明了搜到了一个连通块;不在dfs里加,防止二次加 cout<<cnt<<endl;//输出,没啥好说的 return 0;//好习惯 }
球球点个赞👍
- 1
信息
- ID
- 2053
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 5
- 标签
- (无)
- 递交数
- 206
- 已通过
- 82
- 上传者