HDU1247 Hat’s Words(Trie树)
2016-01-26 20:40
351 查看
常规做法是枚举每个字符串每个位置,时间复杂度O(n*len*len),(建字典树O(n*len))。
然而我看这题第一眼想的是时间复杂度O(n*len)的算法。。就是建正反两棵字典树,每个字符串跑分别跑正反一遍字典树,再看看正反跑的结果能不能拼成原串。
然而常数太大了点,并没什么卵用。。
然而我看这题第一眼想的是时间复杂度O(n*len)的算法。。就是建正反两棵字典树,每个字符串跑分别跑正反一遍字典树,再看看正反跑的结果能不能拼成原串。
然而常数太大了点,并没什么卵用。。
#include<cstdio> #include<cstring> using namespace std; #define MAXL 22 #define MAXN 50100 int ch0[MAXN*MAXL][26],tn0,ch1[MAXN*MAXL][26],tn1; bool flag[2][MAXN*MAXL]; void insert(char *s){ int x=0,len=strlen(s); for(int i=0; i<len; ++i){ int y=s[i]-'a'; if(ch0[x][y]==0) ch0[x][y]=++tn0; x=ch0[x][y]; } flag[0][x]=1; x=0; for(int i=len-1; i>=0; --i){ int y=s[i]-'a'; if(ch1[x][y]==0) ch1[x][y]=++tn1; x=ch1[x][y]; } flag[1][x]=1; } char path[MAXL]; bool vis[2][MAXL]; void query(int len){ memset(vis,0,sizeof(vis)); int x=0; for(int i=0; i<len; ++i){ int y=path[i]-'a'; if(ch0[x][y]==0) break; x=ch0[x][y]; if(flag[0][x]) vis[0][i]=1; } x=0; for(int i=len-1; i>=0; --i){ int y=path[i]-'a'; if(ch1[x][y]==0) break; x=ch1[x][y]; if(flag[1][x]) vis[1][i]=1; } } void dfs(int x,int k){ if(flag[0][x]){ query(k); bool ishat=0; for(int i=1; i<k; ++i){ if(vis[0][i-1] && vis[1][i]){ ishat=1; break; } } if(ishat){ for(int i=0; i<k; ++i) putchar(path[i]); putchar('\n'); } } for(int i=0; i<26; ++i){ if(ch0[x][i]){ path[k]=i+'a'; dfs(ch0[x][i],k+1); } } } int main(){ char str[MAXL]; while(~scanf("%s",str)) insert(str); dfs(0,0); return 0; }
相关文章推荐
- HOJ 1438 The Tower of Babylon(线性DP)
- python数据结构
- POJ 1005 I Think I Need a Houseboat
- C#编写控制台简单聊天机器人
- 三分钟教你轻松掌握 grep 命令中的正则表达式
- Hadoop平台简述
- numpy
- JavaSE入门学习11:Java面向对象之类和对象
- 发现一个在线同步jade html翻译器
- Delphi 调试
- hadoop - hadoop2.6 分布式 - 集群环境搭建 - Hadoop 2.6 分布式安装配置与启动
- Swift基本概念
- UIAlertController的使用——创建提示窗口
- 自定义View的成长之路
- java第一弹--JRE和JDK的概述
- Android ListView点击展开收起效果(一)
- PHP curl 上传文件版本兼容问题
- HDU 1243 反恐训练营(最长公共序列)
- 如何制作一款像超级玛丽兄弟一样基于平台的游戏
- PHP命名空间 namespace 和 自动加载