题目大意:通俗点讲,就是能否从给出的单词中找到一个以'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;
}