题目大意:通俗点讲,就是能否从给出的单词中找到一个以'b'开头,以'm'结尾的单词序列。如果可以就返回Yes.,否则返回No.
解题思路:DFS
1)用st[]、et[]记录每一个单词的开始字母与结束字母,用vis[]来标记某一个单词是某一个单词是否已经访问过.用t来计算单词数.
用ok来标记是否成功
2)如果某一个单词不是以b开头则直接跳过。否则,对该单词进行深搜。如果该单词的结束字母为m则返回成功。否则,遍历所有单词
好到一个开始字符与当前深搜单词的结束字符相同的单词继续深搜。。。
代码如下:
/*
* 1181_1.cpp
*
* Created on: 2013年8月22日
* Author: Administrator
*/
#include<iostream>
using namespace std;
const int maxn = 100000;
/**
* st[] :用来标记每个单词的第一个字母
* et[] :用来标记每个单词的最后一个字母
* vis[] :用来标记某一个单词是否已经被访问过
* t :用来计算总单词数
* ok :单端是否能成功
*/
char st[maxn], et[maxn];
int vis[maxn], t;
bool ok;
//x :当前搜索到的单词的序号
void DFS(int x) {
//如果已经成功
if (ok) {
return;
}
//如果该单词的最后一个字母是m
if (et[x] == 'm') {
ok = true;
return;
}
//遍历状态
for (int i = 0; i < t; ++i) {
//如果第i个单词已经访问过||第i个单词的首字母!=当前访问单词得分最后一个字母
if (vis[i] || st[i] != et[x]) {
continue;//搜索下一个单词
}
vis[i] = 1;
DFS(i);
vis[i] = 0;
}
}
int main() {
string s;
while (cin >> s) {
t = 0;
while (s[0] != '0') {
st[t] = s[0];
et[t++] = s[s.size() - 1];
cin >> s;
}
memset(vis, 0, sizeof(vis));
ok = false;
for (int i = 0; i < t; ++i) {
if (st[i] != 'b') {
continue;
}
vis[i] = 1;
DFS(i);
}
if (ok) {
puts("Yes.");
} else {
puts("No.");
}
}
return 0;
}