【COCI11-12 #5】覆盖字符串
来源:互联网 发布:linux配置路由表命令 编辑:程序博客网 时间:2024/04/29 06:19
题目描述:
给出一个长度为N的小写字母串,现在Mirko有M个若干长度为Li的小写字符串。Mirko要用这M个字符串去覆盖给出的那个字符串的。覆盖时,必须保证:
1.Mirko的字符串不能拆开,旋转;
2.Mirko的字符串必须和给出的字符串的某一连续段完全一致才能覆盖,
3.若干次覆盖可以部分重叠
4.Mirko的字符串可以无限使用。
求给出的字符串当中,有多少个字母是无法覆盖的。
题目解析:使用AC自动机在字符串中查找最开始需要查找的内容,然后再查找的同时存储每一位字符串所对应的单词的编号,然后用【差分数组】处理字符串的覆盖的问题,最后统计覆盖了的数量用总数减去被覆盖的数量就是答案这道题超坑,要二分数组大小不然不是内存超限就是运行错误
95%:
#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#include <iostream>using namespace std;const int MAXN = 3500000;int ch[MAXN+1][26];int val[MAXN+10];int F[MAXN+10];int last[MAXN+10];int vis[MAXN+10];int sz, End[MAXN+10];struct _AC{ inline int idx(char s){ return s - 'a'; } inline void insert(char *s, int id){ int now = 0, len = strlen(s); for(int i=0;i<len;i++){ int u = idx(s[i]); if(!ch[now][u]){ ch[now][u] = ++sz; memset(ch[sz],0,sizeof ch[sz]); val[sz] = 0; } now = ch[now][u]; } val[now] = id; } void GetTrail(){ queue<int> que; for(int i=0;i<26;i++){ if(ch[0][i]){ que.push(ch[0][i]); F[ch[0][i]] = 0; last[ch[0][i]] = 0; } } while(!que.empty()){ int u = que.front(); que.pop(); for(int i=0;i<26;i++){ int son = ch[u][i]; if(!son) continue; que.push(son); int fa = F[u]; while(fa && !ch[fa][i]) fa = F[fa]; F[son] = ch[fa][i]; last[son] = val[F[son]] ? F[son] : last[F[son]]; } } } void Find(char *text){ GetTrail(); int now = 0; int len = strlen(text); for(int i=0;i<len;i++){ int id = idx(text[i]); while(now && !ch[now][id]) now = F[now]; now = ch[now][id]; if(val[now]) End[i] = val[now]; else End[i] = val[last[now]]; } }};char tmp[300010], tmp2[6000][5001];int main(){ _AC ac; int n,m; scanf("%d", &n); scanf("%s", tmp); scanf("%d", &m); for(int i=1;i<=m;i++){ scanf("%s", tmp2[i]); ac.insert(tmp2[i],i); } ac.Find(tmp); int ans = 0; for(int i=0;i<n;i++){ if(End[i] == 0) continue; vis[i-strlen(tmp2[End[i]])+1]++, vis[i+1]--; } int now = 0; for(int i=0;i<n;i++){ now += vis[i]; if(now > 0) ans ++; } printf("%d\n", strlen(tmp) - ans); return 0;}
100%:
#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>using namespace std;const int MAX_NODE = 4400000;const int MAXN = 300000;int ch[MAX_NODE][26];int val[MAX_NODE];int F[MAX_NODE];int last[MAX_NODE];int vis[MAXN+10];int sz, que[MAX_NODE]; inline int idx(char s){ return s - 'a'; } inline void insert(char *s){ int now = 0, len = strlen(s); for(int i=0;i<len;i++){ int u = idx(s[i]); if(!ch[now][u]) ch[now][u] = ++sz; now = ch[now][u]; } val[now] = len; } void GetTrail(){ int l = 0, r = 0, son, u; for(int i=0;i<26;i++) if(ch[0][i]) que[r++] = ch[0][i]; while(l < r){ u = que[l++]; for(int i=0;i<26;i++){ son = ch[u][i]; if(!son){ ch[u][i] = ch[F[u]][i]; continue; } que[r++] = son; F[son] = ch[F[u]][i]; last[son] = val[F[son]] ? F[son] : last[F[son]]; } } } void Find(char *text){ GetTrail(); int now = 0; int len = strlen(text); for(int i=0;i<len;i++){ int id = idx(text[i]); while(now && !ch[now][id]) now = F[now]; now = ch[now][id]; if(val[now]) vis[i-val[now]+1] ++, vis[i+1]--; else vis[i-val[last[now]]+1] ++, vis[i+1]--; } }char tmp[MAXN+10],tmp2[5001];int main(){ int n,m; scanf("%d", &n); scanf("%s", tmp); scanf("%d", &m); for(int i=1;i<=m;i++){ scanf("%s", tmp2); insert(tmp2); } Find(tmp); int ans = 0;int now = 0; for(int i=0;i<n;i++){ now += vis[i]; if(now > 0) ans ++; } printf("%d\n", strlen(tmp) - ans); return 0;}
0 0
- 【COCI11-12 #5】覆盖字符串
- [COCI11-12 4#]删数游戏(版本2)
- #COCI11-12 #4 #纠结的数(二分+枚举+容斥)
- POJ 2185 (字符串最小覆盖)
- BZOJ 4560 [JLoi2016]字符串覆盖
- 关于字符串覆盖问题的解答。
- 字符串窗口覆盖 Minimum Window Substring
- json字符串插入节点或者覆盖节点
- iOS字符串的各种用法(字符串插入、字符串覆盖、字符串截取、分割字符串)
- iOS字符串的各种用法(字符串插入、字符串覆盖、字符串截取、分割字符串)
- 覆盖物-TextOverlay-(12)
- 覆盖
- 覆盖
- 覆盖
- 覆盖
- 覆盖
- 覆盖
- Java 将字符串换行不覆盖写入txt文件
- Codeforces Round #288 (Div. 2)
- Step Tree - 安装eclipse及中文包
- Unicode、UTF-8 和 ISO8859-1到底有什么区别
- 学习是个过程别轻言放弃
- 线程同步之条件变量使用手记线程同步之条件变量使用手记
- 【COCI11-12 #5】覆盖字符串
- php开源程序
- CString类以及很多很全面的与之相关的处理函数
- 校门外的树 区间处理
- 【分享】一张unix发展史简图
- 指针是C/C++语言的特色
- seo优化
- UML6种关系的总结
- AngularJS ui-router 中的query string参数