6 solutions
-
1
#include <bits/stdc++.h> using namespace std; int movex[4]={-1, 1, 0, 0}; int movey[4]={0, 0, -1, 1}; int w, h; char chess[25][25]; bool vistor[25][25]; int x, y; int ans=1; void dfs(int x, int y) { vistor[x][y]=true;//走过的地方不能走 // cout << x << " " << y << endl; for(int i = 0;i < 4; i++) { int ny=y+movey[i]; int nx=x+movex[i]; if(vistor[nx][ny]==false&&nx>=1&&ny>=1&&nx<=w&&ny<=h)//不越界且没走过且能走 { ans++; dfs(nx, ny); } } } int main() { while (cin >> h >> w) { if(h==0 && w==0) return 0;//退出 //重置 for(int i = 1; i <= w; i++) { for(int j = 1; j <= h; j++) { vistor[i][j]=false; } } ans=1; for(int i = 1; i <= w; i++) { for(int j = 1; j <= h; j++) { cin >> chess[i][j]; if(chess[i][j]=='@') { x=i; y=j; } if(chess[i][j]=='#') { vistor[i][j]=true; } } } dfs(x, y); cout << ans << endl; } return 0; }
-
1
题目大意
有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。
你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。
请写一个程序,计算你总共能够到达多少块黑色的瓷砖。
每个字符表示一块瓷砖的颜色,规则如下:
- .:黑色的瓷砖;
- #:白色的瓷砖;
- @:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。
解题代码
#include <bits/stdc++.h> using namespace std; char a[105][105]; int flag[1005][1005], cnt = 1, n, m; void dfs(int x, int y) { for (int i = 1; i <= 4; i++) { int dx, dy; if (i == 1) dx = x + 1, dy = y; else if (i == 2) dx = x - 1, dy = y; else if (i == 3) dx = x, dy = y + 1; else dx = x, dy = y - 1; if (dx >= 1 && dy >= 1 && dx <= n && dy <= m && a[dx][dy] == '.' && !flag[dx][dy]) // 浅浅剪一下枝 { flag[dx][dy] = true; cnt++; dfs(dx,dy); } } } int main() { while (1) { cin >> m >> n; if(n == m && n == 0) return 0; // 一定要写这个,不然直接死循环 int x, y; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> a[i][j]; if (a[i][j] == '@') x = i, y = j; // 找到了黑色的瓷砖 flag[i][j] = false; // flag重新变为false } } dfs(x, y); // 进行dfs cout << cnt << endl; // 输出答案 cnt = 1; // cnt重新变为1 } }
-
-1
#include<bits/stdc++.h> using namespace std; char c[1001][1001]; bool vis[1001][1001]; const int dx[8]={0,0,1,-1,-1,1,-1,1}; const int dy[8]={1,-1,0,0,-1,1,1,-1}; int cnt=0; int n,m; void dfs(int x,int y){ cnt++;//个数加1 for(int i=0;i<4;i++){ int nx=dx[i]+x; int ny=dy[i]+y; if(nx<1||ny<1||nx>m||ny>n||vis[nx][ny]==1||c[nx][ny]=='#')continue;//简单标记 vis[nx][ny]=1; dfs(nx,ny); } } int main(){ //类P1451. 求细胞数量,深度优先搜索 while(cin>>n>>m){ if(n==0&&m==0)break; int x,y; //每次刷新所有标记类数组 memset(c,'0',sizeof(c)); memset(vis,0,sizeof(vis)); for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ cin>>c[i][j]; if(c[i][j]=='@'){ x=i; y=j; } } } //可连通的一次能走完 vis[x][y]=1;//特别注意!不能忘起始位置! dfs(x,y); cout<<cnt<<'\n'; cnt=0; } return 0; }
-
-1
一种新的思路: 洪水填充
在起点进行一次洪水填充,统计标记的个数
#include<iostream> #include<cstring> using namespace std; int xl[4]={0,0,1,-1}; int yl[4]={1,-1,0,0}; int n,m,sx,sy,sum; char g[25][25]; bool vis[25][25]; void dfs(int x,int y)//洪水填充 { vis[x][y]=1; for(int i=0;i<4;i++) { int xs=x+xl[i]; int ys=y+yl[i]; if(xs>0 && xs<=n && ys>0 && ys<=m && g[xs][ys]=='.' && !vis[xs][ys]) dfs(xs,ys); } } int main() { while(1) { memset(g,0,sizeof g); memset(vis,0,sizeof vis); sum=0; cin>>m>>n; if(m==0 && n==0)//是否结束 return 0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>g[i][j]; if(g[i][j]=='@') sx=i,sy=j; } dfs(sx,sy); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) sum+=vis[i][j];//统计走过的个数 cout<<sum<<"\n"; } return 0; }
-
-1
BFS做法,可能有亿点复杂………………
#include<bits/stdc++.h> using namespace std; struct s{ int x,y; }; queue<s> q; int fx[10]={0,1,0,-1},fy[10]={1,0,-1,0},ans=1; string arr[110]; int main(){ while(true){ int n,m,sx,sy,ans=1; cin>>n>>m; if(n==0 && m==0) break; for(int i=0;i<m;i++){ cin>>arr[i]; for(int j=0;j<n;j++){ if(arr[i][j]=='@') sx=i,sy=j; } } q.push({sx,sy}); while(q.size()){ int x=q.front().x,y=q.front().y; q.pop(); for(int i=0;i<4;i++){ if(x+fx[i]>=0 && x+fx[i]<m && y+fy[i]>=0 && y+fy[i]<n && arr[x+fx[i]][y+fy[i]]=='.'){ ans++; q.push({x+fx[i],y+fy[i]}); arr[x+fx[i]][y+fy[i]]='#'; } } } cout<<ans<<'\n'; } return 0; }
-
-1
AC题解(附详细解析)
#include<bits/stdc++.h>//祖传开头 using namespace std; bool visited[25][25];//标记该地砖是否已被访问 char rm[25][25];//"room"的缩写,以矩阵形式存储房间概况 int step=1;//记录步数,以此判断是否已无路可走 int w0,h0;//由于w,h是函数的参数变量,所以需要w0,h0两个恒变量存储输入的w,h值 int dfs(int x,int y,int w,int h,int sum){//搜索函数 visited[x][y]=true;//每经过一块瓷砖就进行标记,以免重复走。 step++;//步数++ if(step==w0*h0*4){//约等于重复走上4遍,保证的确无路可走再return return sum;//return计算地砖的总和 } if(x-1>=0 and visited[x-1][y]==0){//往下的四个条件判断分别代表上下左右,每探测一步就计数,递归 sum++; step++; sum+=dfs(x-1,y,w,h,0); } if(x+1<h and visited[x+1][y]==0){ sum++; step++; sum+=dfs(x+1,y,w,h,0); } if(y-1>=0 and visited[x][y-1]==0){ sum++; step++; sum+=dfs(x,y-1,w,h,0); } if(y+1<w and visited[x][y+1]==0){ sum++; step++; sum+=dfs(x,y+1,w,h,0); } return sum;//再将总和return } int main(){ int w,h,x,y;//w,h为题目要求变量,x,y分别代表x坐标,y坐标 while(cin>>w>>h){//因为题目有多个测试样例,所以while if(w==0&&h==0){//当输入0 0时,程序结束 return 0; } for(int i=0;i<h;i++){//双重循环输入矩阵 for(int j=0;j<w;j++){ cin>>rm[i][j]; if(rm[i][j]=='@'){//记录起始点x,y坐标 x=i; y=j; visited[i][j]=true;//起点视为已经过 } if(rm[i][j]=='#'){//白色地砖也视为已经过,省去了函数判断 visited[i][j]=1; } } } w0=w;//使用w0,h0记录w(width)和h(height) h0=h; cout<<dfs(x,y,w,h,1)<<endl;//调用函数,由于起点也是黑地砖,所以sum初始为1 memset(visited,0,sizeof(visited));//记得初始化,本人亲测不初始化只有20分 step=0; } return 0;//祖传结尾 } //附:感谢大佬在A1215发的题解,给了我启发
- 1
Information
- ID
- 702
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 7
- Tags
- # Submissions
- 115
- Accepted
- 29
- Uploaded By