南邮 OJ 1850 D. 寻找单词

D. 寻找单词

时间限制(普通/Java) :  10000 MS/ 30000 MS          运行内存限制 : 65536 KByte
总提交 : 118            测试通过 : 31 

比赛描述

    给出一个n×m的棋盘,棋盘的每个格子里都填了一个字母,另外给一份单词表,要求在棋盘中找出每一个可以被找到的单词的位置。
    单词必须和棋盘中一条不间断的直线匹配,大小写不敏感(即大写字母和相应的小写字母被认为是相同的)。这条直线可以使水平、竖直、对角线的八个方向之一。


输入

    第一行包含一个正整数T(T≤1000),表示样例个数,接下来给出T组测试用例。
    每组测试用例包含多行,第一行有两个正整数n和m(1≤n, m≤100)。接下来n行每行有m个字母,即一个包含且只包含字母的棋盘。下一行只有一个整数k(1≤k≤50)。接下来k行是待查找的单词,每行一个。这些单词也只包含字母,不包含空格、连字符或者其他非字母字符。

输出

    每组测试用例输出k行。每行输出两个正整数,对应表示第k个单词在棋盘中的起始位置,这一对整数以一个空格隔开。第一个数代表这个单词首字母的行号(最上方为第1行),第二个数代表这个单词首字母的列号(最左边为第1列)。如果一个单词在棋盘中不止出现一次,则输出首字母位置最靠上的那一个,如果仍有多解,则输出这些解中最靠左侧的那一个。如果单词未被找到,则输出-1 -1。
    输出时相邻两组数据之间用一个空行隔开。

样例输入

1
8 11
abcDEFGhigg
hEbkWalDork
FtyAwaldORm
FtsimrLqsrc
byoArBeDeyv
Klcbqwikomk
strEBGadhrb
yUiqlxcnBjf
4
Waldorf
Bambi
Betty
Dagbert

样例输出

2 5
2 3
1 2
7 8

提示

    由于排版问题,样例输入的棋盘列未能很好的对齐,但在数位编辑器里,行列是严格对齐的,也即棋盘是个标准的矩阵。

题目来源

ACM爱好者协会




#include<iostream>
#define N 501
char a[N][N];
char b[N];
int x,y,n,m;
int dirX[8]={-1,-1,-1, 0, 0, 1, 1, 1};	//WA
int dirY[8]={-1, 0, 1, 1,-1, 1, 0,-1};

bool fit(){
	int dir,i,currentX,currentY;
	for(dir=0; dir<8; dir++){
		currentX = x;
		currentY = y;
		for(i=0; 
			currentX>=0 && currentX<n && 
			currentY>=0 && currentY<m &&
			b[i]==a[currentX][currentY];
			i++,currentX+=dirX[dir],currentY+=dirY[dir]){
			if(!b[i+1]){
				return 1;
			}
		}
	}
	return 0;
}

bool match(){
	bool ok=0;
	for(x=0; x<n && !ok; x++){
		for(y=0; y<m && !ok; y++){
			ok = fit();
		}
	}
	return ok;
}

int main(){
//	freopen("test.txt","r",stdin);
	int T,i,j,k;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&m);
		for(i=0; i<n; i++){
			scanf("%s",a+i);
		}
		for(i=0; i<n; i++){
			for(j=0; j<m; j++){
				a[i][j] |= 32;
			}
		}
		scanf("%d",&k);
		while(k--){
			scanf("%s",b);
			for(char *c=b; *c; c++){
				*c |= 32;
			}
			if(match()){
				printf("%d %d\n",x,y);
			}else{
				printf("-1 -1\n");		//WA
			}
		}
		if(T){
			printf("\n");				//PE
		}
	}
}



你可能感兴趣的:(ACM,南邮OJ,寻找单词)