URAL 1002 Phone Numbers
2015-11-26 19:56
369 查看
传送门
直接求出每个串出现位置,DP即可。
直接求出每个串出现位置,DP即可。
#include <bits/stdc++.h> using namespace std; #define prt(k) cerr<<#k" = "<<k<<endl typedef long long LL; const int inf = 0x3f3f3f3f; #define pb push_back const int N = 50500; const int M = N * 50; int ch[M][10], fail[M], id[M], len ; int L; int n; map<char, int> mp; namespace AC { int newnode() { memset(ch[L],-1,sizeof ch[L]); id[L++] = 0; return L-1; } void init() { L = 0; newnode(); } void insert(char s[], int ID) { int u = 0, len = strlen(s); for (int i=0;i<len;i++) { int c = s[i] - '0'; if (ch[u][c] == -1) ch[u][c]= newnode(); u = ch[u][c]; } id[u] = ID; } void AC_build() { queue<int> q; for (int i=0;i<10;i++) { int &v = ch[0][i]; if (v != -1) { q.push(v); fail[v] = 0; } else v = 0; } while (!q.empty()) { int u = q.front(); q.pop(); for (int i=0;i<10;i++) { int &v = ch[u][i]; if (v==-1) { v = ch[fail[u]][i]; } else { fail[v] = ch[fail[u]][i]; q.push(v); } } } } vector<int> pos ; void query(char buf[]) { int n = strlen(buf); int u=0; for(int i=0;i<n;i++) { u=ch[u][buf[i]-'0']; for(int v=u;v!=0;v=fail[v]) { if (id[v] > 0) { pos[i-len[id[v]]+1].push_back(id[v]); } } } } }; using namespace AC; #define For(i,l,r) for (char i=l;i<=r;i++) char T[233], s [52], old [55]; int TL; int dp ; int pre ; int main() { mp['i'] = mp['j'] = 1; mp['a'] = mp['b'] = mp['c'] = 2; For(i,'d','f') mp[i]=3; For(i, 'g', 'h') mp[i] = 4; For(i,'k','l') mp[i] = 5; For(i,'m','n') mp[i] = 6; For(i,'p','s') mp[i] = 7; For(i, 't', 'v') mp[i] = 8; For(i, 'w', 'y') mp[i] = 9; mp['o'] = mp['q'] = mp['z'] = 0; while (scanf("%s", T) == 1 ) { if (strcmp(T,"-1")==0) break; TL = strlen(T); for (int i=0;i<TL;i++) pos[i].clear(); cin>>n; L = 0; newnode(); for (int i=1;i<=n;i++) { scanf("%s", s[i]); len[i] = strlen(s[i]); strcpy(old[i], s[i]); for (int j=0;j<len[i];j++) s[i][j] = mp[s[i][j]] + '0'; insert(s[i], i); } AC_build(); query(T); int m = TL; memset(dp, 63, sizeof dp); memset(pre, -1, sizeof pre); dp[0] = 0; for (int i=0;i<m;i++) { for (auto x : pos[i]) { if (dp[i+len[x]] > dp[i] + 1) { dp[i+len[x]] = dp[i] + 1; pre[i+len[x]] = x; } } } if (dp[m] == inf) { puts("No solution."); continue; } stack<int> stk; int i = m; while (i!=0 && pre[i]!=-1) { stk.push(pre[i]); i -= len[pre[i]]; } printf("%s", old[stk.top()]); stk.pop(); while (!stk.empty()) { printf(" %s", old[stk.top()]); stk.pop(); } putchar(10); } return 0; }
相关文章推荐
- 【SGU 128】snake 线段树
- PS: Understanding deep features with computer-generated imagery___ICCV2015
- 有趣的单精度浮点数(float)
- 【C语言】两个有序单链表的合并
- 互联网产品 要不要做用户调研
- 学习排序 Learning to Rank 小结
- 工具栏CollectionsJAVA128
- Android高效获取指定类型文件,获取文件不求人!
- Redis常用命令
- Visual Studio的函数unsafe报错问题
- 整数划分问题
- 将文件或目录拷贝到另一个Linux系统的命令scp
- HDOJ--1262--寻找素数对
- AT&T汇编基础]
- 3D引擎:Horde3D:读取Shader文件流程(二)
- 互联网产品 要不要做用户调研
- Android MVP架构和MVC架构比较(有代码示例)
- UILabel的使用
- Redis 集群规范(中文稿)(MOVED错误码及ASK错误码
- leetcode_First Bad Version