给一个 n*m 的棋盘, 棋盘每个格子颜色都是一个大写字母,
以一个格子为起点, 每次只能走上下左右四个方向, 并且每个格子只能走一次,
要求 :
至少经过四个颜色相同的不同格子最终走回起点
若可以输出 Yes, 否则 No.
直接 dfs, 一直忘记回溯起点, wa到蹦! 唉…
后来考虑了下, 的确完全没必要用一个数组来只标记一个起点, 实在是非常浪费,
完全可以用 vis[i][j] = -1 来标记起点,
再或者用两个变量记录起点横纵坐标, 在递归出口的时候判断下即可 …
不过为了强迫症式的整洁, 我就不改了 ^ _ ^
就当复习了 dfs 了吧, 顺便用一用 get 到的新技能, 不用方向数组来枚举方向, emm, 很巧妙啊, 见方向遍历方式二
#include
using namespace std;
const int MAXN = 55;
int n, m;
char a[MAXN][MAXN];
bool vis[MAXN][MAXN];
bool isStratPos[MAXN][MAXN];
bool ans = false;
int nxt[4][2] = {
{ 0, 1 },
{ 1, 0 },
{ 0, -1 },
{ -1, 0 } };
void dfs ( char ch, int x, int y, int len ) {
if ( ans ) return;
for ( int k = 0; k < 4; ++k ) {
int tx = x+nxt[k][0], ty = y+nxt[k][1];
if ( isStratPos[tx][ty] && len>3 ) {
ans = true;
return;
}
if ( tx>=n || tx<0 || ty>=m || ty<0 || vis[tx][ty] || ch!=a[tx][ty] )
continue;
vis[tx][ty] = true;
dfs ( ch, tx, ty, len+1 );
vis[tx][ty] = false;
}
}
int main ( ) {
memset ( vis, false, sizeof(vis) );
memset ( isStratPos, false, sizeof(isStratPos) );
cin >> n >> m;
for ( int i = 0; i < n; ++i )
cin >> a[i];
for ( int i = 0; i < n; ++i ) {
for ( int j = 0; j < m; ++j ) {
isStratPos[i][j] = true;
vis[i][j] = true;
dfs ( a[i][j], i, j, 1 );
if ( ans ) break;
vis[i][j] = false;
isStratPos[i][j] = false;
}
if ( ans ) break;
}
cout << ( ans ? "Yes" : "No") << endl;
return 0;
}
#include
using namespace std;
const int MAXN = 55;
int n, m;
char a[MAXN][MAXN];
bool vis[MAXN][MAXN];
bool isStratPos[MAXN][MAXN];
bool ans = false;
void dfs ( char ch, int x, int y, int len ) {
if ( ans ) return;
for ( int i = -1; i <= 1; ++i ) { // -1 : _ 0 _
for ( int j = -1; j <= 1; ++j ) { // 0 : -1 _ 1
if ( i==j || i&&j ) continue; // 1 : _ 0 _
int tx = x+i, ty = y+j;
if ( isStratPos[tx][ty] && len>3 ) {
ans = true;
return;
}
if ( tx>=n || tx<0 || ty>=m || ty<0 || vis[tx][ty] || ch!=a[tx][ty] )
continue;
vis[tx][ty] = true;
dfs ( ch, tx, ty, len+1 );
vis[tx][ty] = false;
}
}
}
int main ( ) {
memset ( vis, false, sizeof(vis) );
memset ( isStratPos, false, sizeof(isStratPos) );
cin >> n >> m;
for ( int i = 0; i < n; ++i )
cin >> a[i];
for ( int i = 0; i < n; ++i ) {
for ( int j = 0; j < m; ++j ) {
isStratPos[i][j] = true;
vis[i][j] = true;
dfs ( a[i][j], i, j, 1 );
if ( ans ) break;
vis[i][j] = false;
isStratPos[i][j] = false;
}
if ( ans ) break;
}
cout << ( ans ? "Yes" : "No") << endl;
return 0;
}
小Biu在玩一个棋盘游戏,这个游戏给出一个n*m的棋盘,并且每个点上有一个棋子,棋子的颜色用一个大写字母表示。
小Biu获得游戏胜利的条件是:
1.选择一个棋子作为起点。
2.每次只能走上下左右四个方格,并且下一步方格的颜色要与当前格颜色相同
3.每个块只能经过一次,要经过不少于4个不同的格子而且最终要走回起点。
问小Biu是否可以赢得游戏的胜利
输入
第一行包含两个整数n和m (2≤n,m≤50):棋盘的行和列。
接下来n行,每行包含一个有m个字母的串,表示当前行每一个点的颜色。每一个字母都是大写字母。
输出
如果小Biu可以获得胜利输出Yes,否则输出No。
数据范围
对于20%的数据,n *m<=10;
对于65%的数据,n *m<=100;
对于100%的数据, n *m<=2500;
输入样例
3 4
AAAA
ABCA
AAAA
输出样例
Yes
样例解释
样例中所有的’A’形成一个环。