题目
福克斯在玩一款手机解迷游戏,这个游戏叫做”两点”。基础级别的时候是在一个n×m单元上玩的。像这样:
![](http://img.51nod.com/upload/000FBEBD/08D26811337C62460000000000000003.jpeg)
每一个单元有包含一个有色点。我们将用不同的大写字母来表示不同的颜色。
这个游戏的关键是要找出一个包含同一颜色的环。看上图中4个蓝点,形成了一个环。一般的,我们将一个序列 d1,d2,...,dk 看成一个环,当且仅当它符合下列条件时:
1. 这k个点不一样,即当 i≠j时, di 和 dj不同。
2. k至少是4。
3. 所有的点是同一种颜色。
4. 对于所有的 1≤i≤k-1: di 和 di+1 是相邻的。还有 dk 和 d1 也应该相邻。单元 x 和单元 y 是相邻的当且仅当他们有公共边。
当给出一幅格点时,请确定里面是否有环。
Input
单组测试数据。 第一行包含两个整数n和m (2≤n,m≤50):板子的行和列。 接下来n行,每行包含一个有m个字母的串,表示当前行每一个点的颜色。每一个字母都是大写字母。
Output
如果有环输出Yes,否则输出No。
Input示例
3 4 AAAA ABCA AAAA 3 4 AAAA ABCA AADA
Output示例
Yes No
思路:
这道题目搞了我好久,虽然感觉简单但是不知道是自己最近弱逼了还是怎么了,写了好久;
开始深搜,后来广搜,发现思路都错了,想着是计数,记录扩展到每个节点的cnt,然后如果当前减去下一个已经发现的大于4就认为ok,没想到这明显是有漏洞的,至少广搜搞不定;
后来重整思路,其实很简单,无论深搜还是广搜,只要点扩展时不要扩展自己的父节点就行,然后一旦碰到已经找过的点肯定是有环的;换种说法,其实就是找环,如何找,也就是先标记已经找到的,如果下次发现扩展的是之前找到的就证明有环;只要防止一种情况,就是从1,1 找到2,1,当2,1扩展时还会扩展1,1,这个时候直接过滤掉就行,不要走老路;
哎,好久不练就是生疏,今天bfs搞定,改天再dfs写一遍吧!
太乱了
代码:
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<queue>
using namespace std;
typedef struct NODE
{
int pos_x;
int pos_y;
int pre_x;
int pre_y;
NODE(int x, int y, int px, int py):pos_x(x),pos_y(y), pre_x(px), pre_y(py)
{
}
}Node;
queue<Node> q;
char arr[55][55];
int flag[55][55];
bool judge_pos(int i, int j, int x, int y, int p_x,int p_y, int n, int m)
{
if (x >= 1 && x <= n && y >= 1 && y <= m && arr[i][j] == arr[x][y] &&( x!=p_x || y!= p_y))
{
if (flag[x][y])
{
return true;
}
else
{
flag[x][y] = true;
Node new_node(x,y,i,j);
q.push(new_node);
}
}
return false;
}
bool solve(int n, int m)
{
while(!q.empty())
{
Node tmp = q.front();
q.pop();
int x = tmp.pos_x;
int y = tmp.pos_y;
int p_x = tmp.pre_x;
int p_y = tmp.pre_y;
if (judge_pos(x,y,x-1,y,p_x, p_y, n,m) ||
judge_pos(x,y,x+1,y,p_x, p_y,n,m)||
judge_pos(x,y,x,y-1,p_x, p_y,n,m)||
judge_pos(x,y,x,y+1,p_x, p_y,n,m))
{
return true;
}
}
return false;
}
int main()
{
int n, m;
while (scanf("%d %d", &n, &m)!=EOF)
{
getchar();
memset(flag, 0, sizeof(flag));
for (int i = 1; i <= n; ++ i)
{
for (int j = 1; j <= m; ++ j)
{
scanf("%c", &arr[i][j]);
}
getchar();
}
bool exit_flag = false;
for (int i = 1; i <= n && !exit_flag; ++ i)
{
for (int j = 1; j <= m && !exit_flag; ++ j)
{
if (!flag[i][j])
{
while(!q.empty())
q.pop();
Node node(i,j,0,0);
q.push(node);
if (solve(n,m))
{
exit_flag = true;
printf("Yes\n");
}
}
}
}
if (!exit_flag)
printf("No\n");
}
return 0;
}