洛谷 P1140 01迷宫 dfs+联通快+打表

https://www.luogu.org/problemnew/show/P1141

T掉的方法 直接dfs: 与联通快的写法差不多,但有个问题 是这样搜会重复好多点,因此最好能把每个联通快的个数保存下来

下次直接找这个数 正确代码在最下面。

#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1000000;
int a[1005][1005];
int vis[1005][1005];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
int n,m;
int ans=0;
void dfs(int x,int y){// 怎么说那 单独联通快的写法 直接搜 搜到全退出递归 注意不回溯!!
	vis[x][y]=1;
	for(int i=0;i<4;i++){
		int nx=x+dx[i];
		int ny=y+dy[i];
		if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&a[nx][ny]!=a[x][y]&&!vis[nx][ny]){
				ans++;
				dfs(nx,ny);	
		}
	}
	return;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
		   char k;
		   cin>>k;
		   a[i][j]=k-'0';	
		}
	}
	while(m--){
		memset(vis,0,sizeof(vis));
		int x,y;
		ans=1;
		cin>>x>>y;
		dfs(x,y);
		cout<<ans<<endl;
	}
} 

正确代码:我觉得其实就是 对多个联通快打表 预先吧每个联通快里的说明联通快的联通格子数

#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1000000;
int a[1005][1005];
int vis[1005][1005];
int ans[1005][1005];
int tmp[1000005][2];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
int n,m;
int num=0;
void dfs(int x,int y){
	num++;
	tmp[num][0]=x;
	tmp[num][1]=y;
	for(int i=0;i<4;i++){
		int nx=x+dx[i];
		int ny=y+dy[i];
		if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&a[nx][ny]!=a[x][y]&&!vis[nx][ny]){
			vis[nx][ny]=1;
			dfs(nx,ny);	
		}
	}
	return;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
		   char k;
		   cin>>k;
		   a[i][j]=k-'0';	
		}
	}
	for(int i=1;i<=n;i++){//多个联通块 
		for(int j=1;j<=n;j++){
			if(!vis[i][j]){
				vis[i][j]=1;
				num=0;
				dfs(i,j);
				for(int k=1;k<=num;k++){
					ans[tmp[k][0]][tmp[k][1]]=num;
				}
			}
		}
	}
	while(m--){
		int x,y;
		cin>>x>>y;
		cout<<ans[x][y]<<endl;
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/gml1999/article/details/88593867