[HDOJ 1247] Hat’s Words [字典树]

69 篇文章 0 订阅
27 篇文章 0 订阅

这题目没说字符串长度和是多少...也没说每个单词最长多长...当成最长20然后过的..

开两个字典树,一个是给出的串构成的,一个是给出的串的逆串构成的,然后对于每个有的单词,看一下他的后缀都有多长的,然后看一下能不能加到他的长度

复杂度O(n),n为总长度


#include <cstdio>
#include <cstring>

using namespace std;

struct Node {
	Node *s[26];
	bool match;
};

bool e[20]={0},f[20];

struct TrieTree {
	Node a[1000000];
	int p;
	Node *root;
	Node *newNode() {
		memset(a[p].s,0,sizeof(a[p].s));
		a[p].match=false;
		return &a[p++];
	}
	TrieTree() {
		p=0;
		root=newNode();
	}
	void insert(char *s) {
		Node *cur=root;
		while (*s!='\0') {
			int t=*(s++)-'a';
			if (cur->s[t]==NULL) cur->s[t]=newNode();
			cur=cur->s[t];
		}
		cur->match=true;
	}
	void check(char *s) {
		int l=0;
		Node *cur=root;
		while (*s!='\0') {
			int t=*(s++)-'a';
			if (cur->s[t]==NULL) return;
			cur=cur->s[t];
			l++;
			if (cur->match) f[l]=true;
		}
	}
};

TrieTree a,b;
char s1[20];
char s2[20];
int ls;

void gets2() {
	ls=strlen(s1);
	for (int i=0;i<ls;i++) s2[i]=s1[ls-i-1];
	s2[ls]='\0';
}

bool check() {
	memset(f,0,sizeof(f));
	b.check(s2);
	for (int i=1;i<ls;i++) {
		if (e[i]&&f[ls-i]) return true;
	}
	return false;
}

void dfs(Node *from,int i) {
	if (from->match) {
		s1[i]='\0';
		gets2();
		if (check()) printf("%s\n",s1);
		e[i]=true;
	}
	for (int j=0;j<26;j++) {
		if (from->s[j]) {
			s1[i]=j+'a';
			dfs(from->s[j],i+1);
		}
	}
	e[i]=false;
}

int main() {
	int i;
	while (scanf("%s",s1)!=EOF) {
		gets2();
		a.insert(s1);
		b.insert(s2);
	}
	dfs(a.root,0);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值