HDU-1247 Hat‘s Words

用字典树,字典树存串,再将串由长度小到大排序,枚举将各个串否成两个子串,判断两个子串是否存在,最后按字典序排序结果串并输出。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e6 + 5;
int tot, trie[N][30];
bool flag[N];
struct abc{
	char s[100];
}ss[50005];
struct cba{
	char s[100];
}ans[50005];
void insert(char *str)
{
   int len = strlen(str);
   int root = 0;
   for(int i = 0; i < len; ++i)
   {
       int id = str[i] - 'a';
       if(!trie[root][id]) trie[root][id] = ++tot;
       root = trie[root][id];
   }
   flag[root] = true;
}
bool find(char *str)
{
    int len = strlen(str);
    for(int i = 1; i < len; ++i)
    {
    	int root = 0, ne = 1;
    	for(int j = 0; j < i; ++j){
    		int id = str[j] - 'a';
    		if(!trie[root][id]){
    			ne = 0;
    			break;
    		}
    		root = trie[root][id];
    	}
    	if(ne && flag[root]){
    		root = 0;
	    	for(int j = i; j < len; ++j){
	    		int id = str[j] - 'a';
	    		if(!trie[root][id]){
	    			ne = 0;
	    			break;
	    		}
	    		root = trie[root][id];
	    	}
	    	if(ne && flag[root]){
	    		return true;
	    	}
    	}
    }
    return false;
}
bool cmp1(struct abc a, struct abc b){
	if(strlen(a.s) < strlen(b.s)){
		return true;
	}
	return false;
}
bool cmp2(struct cba a, struct cba b){
	if(strcmp(a.s, b.s) < 0){
		return true;
	}
	return false;
}
int main()
{
	int cnt = 0, ans_cnt = 0;
	while(scanf("%s", &ss[cnt].s) != EOF){
		++cnt;
	}
	sort(ss, ss + cnt, cmp1);
	for(int i = 0; i < cnt; ++i){
		if(find(ss[i].s)){
			strcpy(ans[ans_cnt].s, ss[i].s);
			++ans_cnt;
		}
		insert(ss[i].s);
	}
	sort(ans, ans + ans_cnt, cmp2);
	for(int i = 0; i < ans_cnt; ++i){
		printf("%s\n", ans[i].s);
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值