洛谷原题:https://www.luogu.com.cn/problem/P2670
样例都过不了,似乎死循环了?是dfs函数写错了吗
#include
#include
#include
using namespace std;
int n,m,cnt;
char c[101][101];
int d[101][101];
int dfs(int a,int b){
int ans=0;
if(c[a][b]=='*')ans++;
for(int i=-1;i<=1;i++)for(int j=-1;j<=1;j++)dfs(a+i,a+j);
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){
cin>>c[i][j];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(c[i][j]=='*')cout<<"*";
else{cnt=dfs(i,j);
cout<"\n";
}
}
return 0;
}
参考GPT和自己的思路:
从代码中看出,确实存在死循环的可能。首先,在 dfs 函数中,for 循环的条件是从 -1 到 1,即八个方向都要遍历,包括当前位置。因此,在遇到一个格子时,无论它的内容是什么,都会被继续遍历它周围的格子,而周围的格子中又包括了自己,就会陷入死循环。
其次,在 dfs 函数中,没有对已访问过的格子做标记,导致可能会重复遍历同一个格子。
修正这个问题,可以将 for 循环的条件从 -1 到 1 改为 -1 到 2,遍历周围的 8 个格子时去掉自己,同时对已访问过的格子做标记,避免重复访问。以下是修正后的代码:
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m,cnt;
char c[101][101];
bool vis[101][101]; // 标记格子是否访问过
int d[101][101];
int dfs(int a,int b){
int ans=0;
if(c[a][b]=='\*') ans++;
vis[a][b] = true;
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
int x = a+i, y = b+j;
if(i==0 && j==0) continue;
if(x<1 || x>n || y<1 || y>m) continue;
if(vis[x][y]) continue;
ans += dfs(x, y);
}
}
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>c[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(c[i][j]=='\*') cout<<"\*";
else{
cnt=dfs(i,j);
cout<<cnt;
}
}
cout<<"\n";
}
return 0;
}
参考GPT和自己的思路:
问题在于dfs函数中的递归调用时传入的参数不正确。应该传入的是a+i和b+j,而不是a和j。因为a和b是当前格子的坐标,需要加上偏移量才能访问周围的格子。另外,针对边界情况的判断也没有考虑到,需要在dfs函数中加上判断条件,以避免数组越界的情况发生。修正后的dfs函数如下:
int dfs(int a,int b){
int ans=0;
if(c[a][b]=='*')ans++;
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
int x=a+i,y=b+j;
if(x>=1&&x<=n&&y>=1&&y<=m&&!(i==0&&j==0)){
ans+=dfs(x,y);
}
}
}
return ans;
}
另外,还需要注意输入的矩阵字符使用了反斜杠转义,应该改为普通的星号符号。修改后的完整代码如下:
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m,cnt;
char c[101][101];
int dfs(int a,int b){
int ans=0;
if(c[a][b]=='*')ans++;
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
int x=a+i,y=b+j;
if(x>=1&&x<=n&&y>=1&&y<=m&&!(i==0&&j==0)){
ans+=dfs(x,y);
}
}
}
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>c[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(c[i][j]=='*')cout<<"*";
else{
cnt=dfs(i,j);
cout<<cnt;
}
}
cout<<"\n";
}
return 0;
}