您的位置:首页 > 其它

51NOD 1416 两点

2018-03-21 20:29 961 查看
1416 两点 题目来源: CodeForces基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题福克斯在玩一款手机解迷游戏,这个游戏叫做”两点”。基础级别的时候是在一个n×m单元上玩的。像这样:


 
每一个单元有包含一个有色点。我们将用不同的大写字母来表示不同的颜色。
这个游戏的关键是要找出一个包含同一颜色的环。看上图中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 4AAAAABCAAAAA3 4AAAAABCAAADAOutput示例YesNo
 
解题思路
我想用的是dfs深度搜索来解决这道问题。由于该题的特殊性,我只需要将走的方向记录下来,并且让其下一次dfs不回到上一点即可。直到它能够走到起点,使全局bool变量从false变为true。若不能,则不改变状态。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int SIZE = 200;
int fx[4] = {0, 0, 1, -1};
int fy[4] = {1, -1, 0, 0};
char maze[SIZE][SIZE];
int d[SIZE][SIZE];
int jilu_x, jilu_y, jilu_fx, m, n;
char jilu;
bool zt;
void dfs(int, int, int);
int main()
{
while(scanf("%d%d", &m, &n) != EOF)
{
zt = false;
for(int i = 0; i < m; i++)
scanf("%s", maze[i]);
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
memset(d, 0, sizeof(d));
d[i][j] = 1;
jilu = maze[i][j];
jilu_x = i, jilu_y = j;
dfs(i, j, 5);
if(zt) break;
}
if(zt) break;
}
if(zt) printf("Yes\n");
else printf("No\n");
}
return 0;
}
void dfs(int x, int y, int hh)
{
for(int i = 0;i < 4; i++)
{
if(hh == 0 && i == 1) continue;
else if(hh == 1 && i == 0) continue;
else if(hh == 2 && i == 3) continue;
else if(hh == 3 && i == 2) continue;
int nx = x + fx[i];
int ny = y + fy[i];
if(0 <= nx && nx < m && 0 <= ny && ny < n && maze[nx][ny] == jilu && d[nx][ny] == 0)
{
d[nx][ny] = 1;
dfs(nx, ny, i);
}
else if(0 <= nx && nx < m && 0 <= ny && ny < n && maze[nx][ny] == jilu && nx == jilu_x && ny == jilu_y) zt = true;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: