10010 - Where's Waldorf?

题意:
在一个给定的字符串矩阵中查找一个单词(当第一个字符匹配后,可以往八个方向查找后面的字符), 返回单词第一次出现的行数及第一个字母所在的列数.

思路:
1. 由于比较时不区分大小写, 所以每行字符串读进来后都选统一转成大写.
2. 查找时, 因为如果一个单词出现超过一次, 也是取其最左上的结果, 所以遍历时, 从左往右, 从上往下进行遍历; 
3. 当第一个字母匹配后, 后面的字母可以向八个方向进行查找, 若全能找到, 则说明找到此单词.
4. 注意是整个单词统一向某一个方向进行查找, 即统一从左向右, 或统一从下往上, 不能说每一个字母都是对其所在位置往八个方向进行查找, 我就是理解错了这一点, 导致 WA 了好多次;

要点:
1. 使用数组 {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {1, -1}, {-1, 1}, {1, 1}}; 可以把{左,右,上,下,左上,左下,右上,右下} 方向的遍历都有效抽像出来, 而不需要单独写八段函数.
2. 使用 transform(line.begin(), line.end(), line.begin(), ::toupper); 把 line 里的字符都转成大写, 这里要注意 ::toupper, 必须加上全局空间标识符, 因为它不属于 std 命名空间.
3. g++ 编译的程序, 如果函数标明了返回 string, 最后却没有返回, 就会报段错误. 记得以前VC下不会的, 难道我记错了?

题目:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=96&page=show_problem&problem=951

代码:

# include <iostream>
# include <string>
# include <cstdio>
# include <vector>
# include <algorithm>
# include <string.h>
using namespace std;

const int DIRECTION_NUM = 8;
const int directions[8][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {1, -1}, {-1, 1}, {1, 1}}; // {左,右,上,下,左上,左下,右上,右下}

// transform 把字符串转成大写, 这里要写成 ::toupper, 不能直接 toupper, 因为这个不是在 std 命名空间里的
// 查找 word 在 grid 中的位置, 返回结果就是 "所在行 第一列 " 组合的字符串
string searchWord(const vector<string>& grid, const string& word)
{	
	const int r = grid.size();
	const int c = grid[0].size();
	int searchedNum = 0;

	for(int i=0; i<r; i++){
		for(int j=0; j<c; j++){

			// 如果第一个字符查到了,就向八个方向遍历后面所有的字符,看是否匹配
			if(grid[i][j] == word[0]){

				for(int d=0; d<DIRECTION_NUM; d++){
					searchedNum = 1;

					for(int k=1; k<word.size(); k++){

						int row = i + directions[d][0] * k;
						int col = j + directions[d][1] * k;

						if(!(row >= 0 && row < r && col >= 0 && col < c)){
							break;
						}

						if(grid[row][col] == word[k]){
							++searchedNum;
						}else{
							break;
						}
					}

					if(searchedNum == word.size()){
						char a[22];
						sprintf(a, "%d %d", i+1, j+1);

						return a;
					}
				}
			}
		}
	}

	// 这里不写 return "not found", 当serache为 false 时,走到这里,就会报段错误 ...
	return "not found";
}


int main(int argc, char const *argv[])
{
	#ifndef ONLINE_JUDGE
		freopen ("10010_i.txt", "r", stdin);  
		freopen ("10010_o.txt", "w", stdout); 
	#endif

	int caseNum;
	cin >> caseNum;

	while(caseNum--){
		int m;
		int n;
		cin >> m >> n;

		vector<string> grid;
		for(int i=0; i<m; i++){
			string line;
			cin >> line;

			// 统一转成大写
			transform(line.begin(), line.end(), line.begin(), ::toupper);

			grid.push_back(line);
		}

		int k;
		cin >> k;
		for(int i=0; i<k; i++){
			string word;
			cin >> word;

			// 统一转成大写
			transform(word.begin(), word.end(), word.begin(), ::toupper);

			cout << searchWord(grid, word) << endl;
		}

		// 除了最后一个,都需要输出空行
		if(caseNum > 0)
			cout << endl;
	}

	return 0;
}

环境:C++ 4.5.3 - GNU C++ Compiler with options: -lm -lcrypt -O2 -pipe -DONLINE_JUDGE

你可能感兴趣的:(where,uva,10010,Waldorf)