Word Puzzle Tri树

Word Puzzle

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 886    Accepted Submission(s): 226

 

Problem Description

Did you heard of a little game named "Word Puzzle" ? If you didn't, what a pity !
In the game, you will be given a rectangular grid of letters, in which several words are hidden. Each word may begin anywhere in the puzzle, and may be oriented in any straight line horizontally, vertically, or diagonally. However, the words must all go down, right, or down-right. A dictionary is also given to you, indicating the words to be found in the grid.

You task is to find the locations of each word within the grid.

Input

There is only one test case.

The first line is two integers R and C separated by a whitespace. R (20 ≤ R ≤ 500) is the number of rows of the grid. C (20 ≤ C ≤ 500) is the number of columns of the grid.

The following R lines, each line will contains exactly C characters without anything else. Each character is in the range 'A' - 'Z'.

A blank line will be followed after the grid.

The following lines, each line contains a unique word in the dictionary. Each word will contain between 1 and 20 characters ( also in the range 'A' - 'Z'). The dictionary consists of at most 10000 words.

-1 means the end of dictionary.
 

Output

For each word, output the "ROW COL"(quotes for clarity) pair, where ROW is the 0-based row in which the first letter of the word is found, and COL is the 0-based column in which the first letter of the word is found. If the same word can be found more than once, the location in the lowest-indexed row should be returned. If there is still a tie, return the location with the lowest-indexed column. If a word cannot be found in the grid, return "-1 -1" for the word.

Sample Input

3 5

HENRY

GAVIN

MAGIC

HENRY

HGM

HAG

MAVIN

-1

Sample Output

0 0

0 0

0 0

-1 -1

Author

XrtGavin@TJU

Source

HDU 2007 Programming Contest - Final

Recommend

lcy   |   We have carefully selected several similar problems for you:  1856 1855 1851 1852 1854 

给你一个不超过500*500的字符矩阵,再给你一些单词,问你这些单词是否出现在矩阵的行或列或对角线中。(只能从左到右,从上到下或从左上到右下)如果出现了多次,就输出最靠左上的位置。

分析:如果用矩阵建立字典树,就会因数据过大而出错。我们不妨用给出的单词建树,然后枚举矩阵中的位置,查询到一个单词就记录下来(只记录最开始的)。因为我们枚举位置的时候是从左上到右下,所以只要保存第一个值就是答案。

读入数据的时候要注意,行末有换行符和空行之类,这里直接用cin和cout,避免了这些可能导致错误的地方。也可以用 scanf("%s", &s) 读入字符串,它也会自动忽略换行符和空行。但 scanf("%c", &s[i][j]) 就不会忽略,需要加一个getchar函数来读入换行符和空行。

代码:

#include <iostream>
#include <string.h>
#include <string>
#include <stdio.h>
using namespace std;
 
struct node                //定义结构体表示Tri树上的节点
{
	node* next[27];       //子节点
	int num;                //记录当前节点是哪一个单词
};
node root;
node *newnode()             //新建一个节点
{
	node * temp=new node;
	temp->num=-1;
	for (int i = 0; i < 27; i++)
	{
		temp->next[i]=NULL;
	}
	return temp;
}
 
int r, c, l, x[10005], y[10005];
char a[505][505];
 
void insert(char *s, int x){
    int len=strlen(s), v;
    node *p=&root;
    for (int i = 0; i < len; i++)
    {
        v=s[i]-'A';
        if (p->next[v]==NULL)          
        	p->next[v]=newnode();
        p=p->next[v];
    }
    p->num=x;
}

void search(int w, int m, int e)
{
	int i=w, j=m;
	node *p=&root;
	while (i<r && j<c)
	{
		int v=a[i][j]-'A';
		if (p->next[v]==NULL) return;
		p=p->next[v];
		if (p->num!=-1)
		{
			if (x[p->num]==-1 && y[p->num]==-1)
			{
				x[p->num]=w;
				y[p->num]=m;
			}
		}
		if (e==1)
		{
			j++;
		}
		else if(e==2)
		{
			i++;
		}
		else if(e==3)
		{
			i++;
			j++;
		}
	}
}

int main()
{
	scanf("%d%d", &r, &c);
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			cin>>a[i][j];
		}
	}

	char s[25];
	l=0;
	while (cin>>s)
	{
		if (s[0]=='-') break;
		insert(s, l);
		x[l]=-1; y[l]=-1;
		l++;
	}

	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			for (int k = 1; k <= 3; k++)
				search(i, j, k);
		}
	}

	for (int i = 0; i < l; i++)
	{
		printf("%d %d\n", x[i], y[i]);
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41703679/article/details/81710978