|
Word Maze(单词迷宫)
| |
描述: |
Word Maze 是一个网络小游戏,你需要找到以字母标注的食物,但要求以给定单词字母的顺序吃掉。如上图,假设给定单词 if,你必须先吃掉i然后才能吃掉f。 但现在你的任务可没有这么简单,你现在处于一个迷宫Maze(n×m的矩阵)当中,里面到处都是以字母标注的食物,但你只能 吃掉能连成给定单词W的食物。 如下图,指定W为“SOLO”,则在地图中红色标注了单词“SOLO”。 注意区分英文字母大小写,你只能上下左右行走。 |
运行时间限制: | 无限制 |
内存限制: | 无限制 |
输入: | 输入第一行包含两个整数n、m(0<n, m<21)分别表示n行m列的矩阵,第二行是长度不超过100的单词W,从第3行到底n+3行是只包含大小 写英文字母的长度为m的字符串。 |
输出: | 如果能在地图中连成给定的单词,则输出“YES”,否则输出“NO”。注意:每个字母只能用一次。 |
样例输入: | 5 5 SOLO CPUCY EKLQH CRSOL EKLQO PGRBC |
样例输出: | YES |
#include <iostream>
#include <vector>
#include <string>
using namespace std;
const int MAX = 30;
int N, M;
string sGoal; // 待匹配字符串
struct Node
{
int row;
int col;
};
char chess[MAX][MAX]; // 记录单词迷宫
bool visit[MAX][MAX]; // visit[i][j] = true表示[i][j]是否已经走过,
bool ava[MAX][MAX]; // ava[i][j] = true表示[i][j]在单词迷宫内
// ava[i][j] = false表示[i][j]已经越界
vector<Node> vec; // 储存符合待匹配字符串起始字符的位置
int r[] = {-1, 0, 1, 0};
int c[] = {0, -1, 0, 1};
// row: 迷宫横坐标 col:迷宫纵坐标 index:已经搜索到符合要求的字符串长度 length:待匹配字符串长度
bool DFS(int row, int col, int index, int length)
{
if(index == length){ // 已经在迷宫内搜索到符合要求的字符串
return true;
}
int i;
for(i = 0; i < 4; i++){ // 0~3表示分别代表上,左,下,右四个方向进行搜索
int rt = row + r[i]; // 根据搜索方向更新坐标
int ct = col + c[i];
if(!visit[rt][ct] && ava[rt][ct] && chess[rt][ct] == sGoal[index]){ // 判断更新后状态是否满足要求
visit[rt][ct] = true;
if( DFS( rt, ct, index+1, length)){ // DFS
return true;
}
visit[rt][ct] = false;
}
}
return false;
}
int main()
{
cin >> N >> M;
cin >> sGoal;
int i,j;
memset(visit, false, sizeof(visit)); // 初始化为false;
memset(ava, false, sizeof(ava));
for(i = 1; i <= N; i++){ // 输入单词迷宫
for(j = 1; j <= M; j++){
char cTemp;
cin >> cTemp;
chess[i][j] = cTemp;
ava[i][j] = true; // 单词迷宫内ava[i][j]=true
if(cTemp == sGoal[0]){ // 将待匹配字符串起始字母作为DFS搜索的起点,节省时间
Node temp;
temp.row = i;
temp.col = j;
vec.push_back(temp);
}
}
}
bool flag = false; // flag = false表示在单词迷宫内没有搜索到待匹配字符
for(i = 0 ; i < vec.size(); i++){
if( DFS(vec[i].row, vec[i].col, 1, sGoal.size())){
cout << "YES" << endl;
flag = true;
break;
}
}
if(!flag){
cout << "NO" << endl;
}
return 0;
}