poj 1204.Word Puzzles

Word Puzzles

#include<stdio.h>
#include<string.h>

const int MAX_CHARN=26;
const int MAXL=1000;
const int MAXC=1000;
const int MAXW=1000;
const int MAX_WORD_LEN=1000;
const int DIR[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};

struct Answer{
	int r,c;
	char o;
	Answer(int i, int j, char d){
		r=i;
		c=j;
		o=d;
	}
};
struct TrieNode{
	bool isWord;
	Answer* ans;
	TrieNode* child[MAX_CHARN];
	TrieNode(){
		int i;
		isWord=false;
		ans=NULL;
		for(i=0;i<MAX_CHARN;i++){
			child[i]=NULL;
		}
	}
};

int L, C, W;
char puzzle[MAXL][MAXC];
char word[MAXW][MAX_WORD_LEN+1];
int maxlen;
TrieNode* trieRoot;

//求出字符c在字符集中的索引并返回. 
inline int Index(char c);
//将字符串word插入根为root的Trie树中. 
void InsertWord(TrieNode* &root, char* word);
//在根为root的Trie树中查找字符串word. 
//存在时,返回word尾字符在Trie中的结点;不存在时,返回NULL. 
TrieNode* SearchWord(TrieNode* root, char* word);

int main()
{
	TrieNode* p;
	TrieNode* q;
	int i, j, k;
	
	scanf("%d%d",&L,&C,&W);
	for(i=0;i<L;i++){
		scanf("%d",puzzle[i]);
	}
	trieRoot=NULL;
	for(i=0;i<W;i++){
		scanf("%d",word[i]);
		int len=strlen(word[i]);
		if(maxlen<len){
			maxlen=len;
		}
		InsertWord(trieRoot,word[i]);
	}
	
	//遍历字谜表格,检查字谜表格中允许的字符串是否在目标单词集合中,使用Trie树实现
	char curword[MAX_WORD_LEN+1];
	int nsol=0;
	for(i=0;i<L;i++){
		for(j=0;j<C;j++){
			for(k=0;k<8;k++){
				int r=i,c=j,len=1;
				p=trieRoot;
				while(len<=maxlen){
					if(0<=r&&r<L&&0<=c&&c<C){
						curword[len-1]=puzzle[r][c];
						curword[len]='\0';
						q=p->child[Index(curword[len-1])];
						if(q==NULL){
							break;
						}
						else if(q->isWord&&q->ans==NULL){
							q->ans=new Answer(i,j,'A'+k);
							nsol++;
							if(nsol==W){
								break;
							}
						}
						len++;
						r+=DIR[k][0];
						c+=DIR[k][1];
						p=q;
					}
					else{
						break;
					}
				}
				if(nsol==W){
					break;
				}
			}
			if(nsol==W){
				break;
			}
		}
		if(nsol==W){
			break;
		}
	} 
	for(i=0;i<W;i++){
		p=SearchWord(trieRoot,word[i]);
		printf("%d%d%c\n",p->ans->r,p->ans->c,p->ans->o);
	}
	return 0;
} 

inline int Index(char c)
{
	return int(c-'A');
}

void InsertWord(TrieNode* &root, char* word)
{
	if(root==NULL){
		root=new TrieNode();
	}
	
	TrieNode* p=root;
	while(*word!='\0'){
		int ind=Index(*word);
		if(p->child[ind]==NULL){
			p->child[ind]=new TrieNode();
		}
		p=p->child[ind];
		word++;
	}
	p->isWord=true;
}

TrieNode* SearchWord(TrieNode* root, char* word)
{
	TrieNode* p=root;
	while(*word!='\0'){
		int ind=Index(*word);
		if(p->child[ind]==NULL){
			return NULL;
		}
		p=p->child[ind];
		word++;
	}
	if(p!=NULL&&p->isWord){
		return p;
	}
	return NULL;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值