HPU 6008 颜色环——dfs

版权声明:那个,最起码帮我加点人气吧,署个名总行吧 https://blog.csdn.net/qq_41670466/article/details/82152490

题目链接,有时可能会崩

1.PNG

2.PNG

输出

3.PNG

输入样例 1

3 4
AAAA
ABCA
AAAA

输出样例 1

Yes

思路分析,其实就是dfs的一个应用,对于判断是否成环只要判这个点是否已经被标记且,这个点所对应的步数跟上一步所对应的步数差值大于3。

在这里我是先把相同颜色的点都用vector+pair来储存,这样方便查找,原因是在a颜色的第一个储存位置开始深搜时,势必会标记其他相同颜色的点,这样如果从这一个点开始搜索都不能搜到环,那么那些在搜索过程中被标记的点也不会搜到,也算是一种剪枝吧。

代码:

#include<bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;
const int maxn = 55;
vector<pii>vec[27];
int vis[maxn][maxn];
char mapp[maxn][maxn];
int step[maxn][maxn];
int dir[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
int flag = 0;
int n, m;

bool check(int x, int y)
{
	if (x >= 1 && x <= n && y >= 1 && y <= m)
		return true;
	else
		return false;
}

void dfs(int x, int y)
{
	vis[x][y] = 1;
	for (int i = 0; i < 4; i++)
	{
		int fx, fy;
		fx = x + dir[i][0];
		fy = y + dir[i][1];
		if (check(fx, fy) == true &&(mapp[fx][fy]==mapp[x][y]))
		{
			if (vis[fx][fy] == 1)
			{
				if (step[x][y] - step[fx][fy] >= 3)
				{
					flag = 1;
					return;
				}
				else continue;
			}
			else if (vis[fx][fy] == 0)
			{
				step[fx][fy] = step[x][y] + 1;
				dfs(fx, fy);
				if (flag == 1) return;
			}
		}
	}
}

void ini()
{
	flag = 0;
	memset(vis, 0, sizeof(vis));
	memset(step, 0, sizeof(step));
	for (int i = 1; i <= 26; i++)
		vec[i].clear();
}

int main()
{
	while (scanf("%d %d", &n, &m) != EOF)
	{
		ini();
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= m; j++)
			{
				cin >> mapp[i][j];
				int t = mapp[i][j] - 64;
				vec[t].push_back(make_pair(i, j));
			}
		}
		for (int i = 1; i <= 26; i++)
		{
			if (vec[i].size() == 0)continue;
			for (int j = 0; j < vec[i].size(); j++)
			{
				pii p = vec[i][j];
				if (vis[p.first][p.second] == 1) continue;
				dfs(p.first, p.second);
				if (flag == 1) break;
			}
			if (flag == 1) break;
		}
		if (flag == 1) printf("Yes\n");
		else if (flag == 0) printf("No\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41670466/article/details/82152490