玄学!用递归版DFS过了,可循环版却……
查看原帖
玄学!用递归版DFS过了,可循环版却……
984289
Lin_last楼主2024/8/19 09:43

如题

这是 递归版

void dfs(int x,int y){
	vis[x][y]=1;
	if(dict[x+1][y]&&dict[x-1][y]&&dict[x][y+1]&&dict[x][y-1])flag=1;
	for(int i=0;i<4;++i){
		int nx=x+dx[i],ny=y+dy[i];
		if((!vis[nx][ny])&&dict[nx][ny])dfs(nx,ny);
	}
}

这是 循环版

//if !empty:top(min)=1
void dfs(node a) {
//	cout<<"function DFS is running!\n";
//	if(vis[a.x][a.y])return;
	st[++top]=a;
//	if(dict[a.x+1][a.y]&&dict[a.x-1][a.y]&&dict[a.x][a.y+1]&&dict[a.x][a.y-1])flag=0;
	while(top!=0) {
//		cout<<"WHILE loop is running!\n";
		int x=st[top].x,y=st[top--].y;
		vis[x][y]=1;
		if(dict[x+1][y]&&dict[x-1][y]&&dict[x][y+1]&&dict[x][y-1])flag=0;
		for(int i=0; i<4; ++i) {
			int nx=x+dx[i],ny=y+dy[i];
			if((!vis[nx][ny])&&dict[nx][ny]){
				st[++top]=node {nx,ny};
			}
		}
	}
	return ;
}

这是 调用DFS的主函数

int main() {
//	freopen("P8662.out","w",stdout);
	cin>>n;
	for(int i=0; i<n; ++i) {
		for(int j=0; j<n; ++j) {
			cin>>m;
			if(m=='#')dict[i][j]=1;
		}
	}
	int ans=0;
	for(int i=0; i<n; ++i) {
		for(int j=0; j<n; ++j) {
			if(dict[i][j]&&!vis[i][j]) {
				flag=1;
				dfs(node {i,j});
				ans+=flag;
//				cout<<"i:"<<i<<" j:"<<j<<"\n";
//				for(int i=0; i<n; ++i) {
//					for(int j=0; j<n; ++j) {
//						cout<<vis[i][j];
//					}
//					cout<<'\n';
//				}
			}
		}
	}

	cout<<ans;
	return 0;
}

玄学的地方是,在用循环版时,调N(保证大于1e3+10)的值,错误的点数量和提示都不一样,意思是,调数组的大小会影响结果(捂脸)。但是用递归版就没问题。

完整代码,附:

#include<bits/stdc++.h>
using namespace std;

const int N=7e3+200;
const int dx[]= {0,0,1,-1};
const int dy[]= {1,-1,0,0};
bool dict[N][N]={0},vis[N][N]={0};
int n,top,flag;
//int st[N][2];
char m;

struct node {
	int x,y;

} st[N];


//if !empty:top(min)=1
void dfs(node a) {
//	cout<<"function DFS is running!\n";
//	if(vis[a.x][a.y])return;
	st[++top]=a;
//	if(dict[a.x+1][a.y]&&dict[a.x-1][a.y]&&dict[a.x][a.y+1]&&dict[a.x][a.y-1])flag=0;
	while(top!=0) {
//		cout<<"WHILE loop is running!\n";
		int x=st[top].x,y=st[top--].y;
		vis[x][y]=1;
		if(dict[x+1][y]&&dict[x-1][y]&&dict[x][y+1]&&dict[x][y-1])flag=0;
		for(int i=0; i<4; ++i) {
			int nx=x+dx[i],ny=y+dy[i];
			if((!vis[nx][ny])&&dict[nx][ny]){
				st[++top]=node {nx,ny};
			}
		}
	}
	return ;
}
//
//void dfs(int x,int y){
//	vis[x][y]=1;
//	if(dict[x+1][y]&&dict[x-1][y]&&dict[x][y+1]&&dict[x][y-1])flag=1;
//	for(int i=0;i<4;++i){
//		int nx=x+dx[i],ny=y+dy[i];
//		if((!vis[nx][ny])&&dict[nx][ny])dfs(nx,ny);
//	}
//}

int main() {
//	freopen("P8662.out","w",stdout);
	cin>>n;
	for(int i=0; i<n; ++i) {
		for(int j=0; j<n; ++j) {
			cin>>m;
			if(m=='#')dict[i][j]=1;
		}
	}
	int ans=0;
	for(int i=0; i<n; ++i) {
		for(int j=0; j<n; ++j) {
			if(dict[i][j]&&!vis[i][j]) {
				flag=1;
				dfs(node {i,j});
				ans+=flag;
//				cout<<"i:"<<i<<" j:"<<j<<"\n";
//				for(int i=0; i<n; ++i) {
//					for(int j=0; j<n; ++j) {
//						cout<<vis[i][j];
//					}
//					cout<<'\n';
//				}
			}
		}
	}

	cout<<ans;
	return 0;
}

求大佬讲解一下(玄关

2024/8/19 09:43
加载中...