cf-edu#5-C The Labyrinth-dfs记忆化搜搜

http://codeforces.com/contest/616/problem/C

 给出一个n*m图,

如 :


*.*
.*.
*.*

求 每个*周围连在一起的点“.”共有多少个,个数+上自己本身,也就是+1。


窝是直接dfs记忆化搜索,求出每个点“.”的联通量,然后标记在同一个联通块中的点通通为mark(唯一标记)

输出的时候,判断*周围四个方向的空点”.“所含的联通量,并判断一下不要重复计算了 【在同一联通块的点】




	int n,m;
char tm[1005][1005]; 
int num[1005][1005];
int dx[8]={0,0,1,-1};
int dy[8]={1,-1,0,0};
int vis[1005][1005];
queue< int* > sb;
int who[1005][1005];
 
int dfs(int i,int j,int mmark)
{
	if (num[i][j]) return num[i][j];
	num[i][j]=1; 
	vis[i][j]=1; 
	who[i][j]=mmark;
	int *t=&num[i][j];
	sb.push(t);
	int k,x,y;
	for (k=0;k<4;k++)
	{
		x=i+dx[k];
		y=j+dy[k]; 
		if (x>=1&&x<=n&&y>=1&&y<=m&&tm[x][y]=='.'&&vis[x][y]==0)
		{
				num[i][j]+=dfs(x,y,mmark);
		} 
	}
	return num[i][j]; 
}
int main()
{
	
	cin>>n>>m;
	int i,j;
	int minnn=2147483647;
	for (i=1;i<=n;i++)
	{
		scanf("%s",tm[i]+1);
	} 
	
	int x,y,k;
	int mark=1;
	for (i=1;i<=n;i++)
	{
		for (j=1;j<=m;j++)
		{
			if (tm[i][j]=='*') continue;
			num[i][j]=dfs(i,j,mark++);
			int *tt;
			while(!sb.empty())
			{
				tt=sb.front();sb.pop();
				*tt=num[i][j];
			}
		}
	} 
	
	for (i=1;i<=n;i++)
	{
		for (j=1;j<=m;j++)
		{
			if (tm[i][j]=='.') printf(".");
			else
			{
				int tmp=1;
				int aa[5];
				int tmp_ok=0;
				for (k=0;k<4;k++)
				{
					x=i+dx[k];
					y=j+dy[k]; 
					if (x>=1&&x<=n&&y>=1&&y<=m)
					{
						if (tm[x][y]=='.' )
						{
							int flag=0;
							for (int h=1;h<=tmp_ok;h++)
							{
								if (who[x][y]==aa[h]) flag=1;
							}
							if (flag)	continue;
							tmp+=num[x][y];
							aa[++tmp_ok]=who[x][y];
						}
					} 
				}
				printf("%d",tmp%10);
			}
		}
		printf("\n");
	} 
	
	
	
	
	return 0;
	
}


后来写的代码
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std; 
const int N=200005;
int id=0;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0,};
char tm[1005][1005];
int col[1005][1005];
int num[1005*1005]; 
    int n,m;
	int ans[1005][1005];
void dfs(int x,int y,int tmp_id)
{
	if (col[x][y]) return ;
	if (tmp_id==0) 
		col[x][y]=++id,tmp_id=id;
	else
		col[x][y]=tmp_id; 
	
	num[tmp_id]++;
	for (int i=0;i<4;i++)
	{
		int tx=x+dx[i];
		int ty=y+dy[i];
		if (!(tx>=1&&tx<=n&&ty>=1&&ty<=m)) continue;
		if (tm[tx][ty]=='*')continue;
		dfs(tx,ty,id);
	}
}
int main()
{
	int i,j,k,tx,ty;
	cin>>n>>m;
	for (i=1;i<=n;i++)
	{
		scanf("%s",tm[i]+1);
	}
	
	for (i=1;i<=n;i++)
	{
		for (j=1;j<=m;j++)
		{
			if (tm[i][j]=='.')
				dfs(i,j,0);
		}
	}
	set<int >sb;
	for (i=1;i<=n;i++)
	{
		for (j=1;j<=m;j++)
		{
			int sum=0;
			if (tm[i][j]=='.')continue;
			sb.clear();
			for (k=0;k<4;k++)
			{
				int tx=i+dx[k];
				int ty=j+dy[k];
				if (!(tx>=1&&tx<=n&&ty>=1&&ty<=m)) continue;
				if (tm[tx][ty]=='.'&&sb.find(col[tx][ty])==sb.end()) 
				{
					sum+=num[col[tx][ty]];
					sb.insert(col[tx][ty]);
				}
			}
			ans[i][j]=sum+1;
		}
	}
	
	for (i=1;i<=n;i++)
	{
		for (j=1;j<=m;j++)
		{
			if (ans[i][j])	printf("%d",ans[i][j]%10);
			else printf(".");
		}
		printf("\n");
	}
	return 0;
}


你可能感兴趣的:(cf-edu#5-C The Labyrinth-dfs记忆化搜搜)