JZOJ 3669【HNOI2014】抄卡组
来源:互联网 发布:软件编程是什么 编辑:程序博客网 时间:2024/05/23 02:03
Description:
Input:
Output:
Sample Input:
3
3
wellplayed
thankyou
pyroblast
2
a*abc
abc*a
2
a*abc
a1234567890abc
Sample Output:
N
N
Y
Data Constraint:
题目大意:
字符串中,*可以替代成任何长度任何模样的字符串,给出T组,每组n个字符串,求两两之间是否能匹配。
题解:
如果n个字符串都带星号,只需要判断字符串的第一个星号之前的字符串是否完全相同,最后一个星号的字符串是否完全相同。
如果有一个不带星号的字符串,用它去和其它的匹配,假设它是A串,待匹配的串是B串,只需要判断星号之间的字符串是否按顺序地出现在A串,用KMP解决即可。
Code:
#include<cstdio>#include<cstring>#include<algorithm>#define fo(i, x, y) for(int i = x; i <= y; i ++)#define fd(i, x, y) for(int i = x; i >= y; i --)#define min(a, b) ((a) < (b) ? (a) : (b))#define max(a, b) ((a) > (b) ? (a) : (b))using namespace std;const int Maxc = 20000005, Maxn = 100005;int T, n, l[Maxn], r[Maxn], p[Maxn];int next[Maxc];char c[Maxc];bool pd(int x, int y) { if(!p[x] && !p[y]) { if(r[x] - l[x] != r[y] - l[y]) return 0; fo(i, 0, r[x] - l[x]) if(c[l[x] + i] != c[l[y] + i]) return 0; return 1; } if(!p[x]) swap(x, y); int u = 0, v = 0; fo(i, l[x], r[x]) {if(c[i] == '*') break; u ++;} fd(i, r[x], l[x]) {if(c[i] == '*') break; v ++;} if(!p[y] && u + v > r[y] - l[y] + 1) return 0; fo(i, 0, u - 1) { if(c[l[y] + i] == '*') break; if(c[l[y] + i] != c[l[x] + i]) return 0; } fo(i, 0, v - 1) { if(c[r[y] - i] == '*') break; if(c[r[y] - i] != c[r[x] - i]) return 0; } return 1;}void Get_next(int x, int y) { next[x] = 0; int i = 0; fo(j, x + 1, y) { while(i > 0 && c[x + i] != c[j]) i = next[x + i - 1]; if(c[x + i] == c[j]) i ++; next[j] = i; }}void Work() { int ans = 1, bz = 0; scanf("%d", &n); fo(i, 1, n) { l[i] = r[i - 1] + 1; r[i] = r[i - 1]; char ch = ' '; for(;! ((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '*'); ch = getchar()); for(; (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '*'; ch = getchar()) c[++ r[i]] = ch; p[i] = 0; fo(j, l[i], r[i]) if(c[j] == '*') p[i] = 1; if(!p[i]) bz = 1; } if(bz == 0) { fo(i, 1, n) { fo(j, i + 1, n) if(!pd(i, j)) { ans = 0; break; } if(ans == 0) break; } if(ans) printf("Y\n"); else printf("N\n"); return; } fo(k, 1, n) if(!p[k]) bz = k; fo(k, 1, n) if(k != bz) { if(!pd(bz, k)) { ans = 0; break; } if(!p[k]) continue; int st = l[bz], en = r[bz], st2 = l[k], en2 = r[k]; fo(i, l[k], r[k]) { if(c[i] == '*') break; st ++; st2 ++; } fd(i, r[k], l[k]) { if(c[i] == '*') break; en --; en2 --; } while(st2 < en2) { st2 ++; fo(d, st2, en2) { if(c[d] == '*') { if(st2 == d) break; Get_next(st2, d - 1); int i = 0, bz = 0; fo(j, st, en) { while(i && c[st2 + i] != c[j]) i = next[st2 + i - 1]; if(c[st2 + i] == c[j]) i ++; if(i == d - st2) { bz = 1; st = j + 1; st2 = d; break; } } if(!bz) ans = 0; break; } } if(ans == 0) break; } if(ans == 0) break; } if(ans) printf("Y\n"); else printf("N\n");}int main() { freopen("hs.in", "r", stdin); freopen("hs.out", "w", stdout); for(scanf("%d", &T); T; T --) Work();}
阅读全文
1 0
- JZOJ 3669【HNOI2014】抄卡组
- BZOJ 3574: [Hnoi2014]抄卡组
- bzoj 3574: [Hnoi2014]抄卡组 (字符串Hash)
- 【HNOI2014】Jabberwocky
- bzoj3572: [Hnoi2014]世界树
- hnoi2014米特运输
- 【BZOJ 3571】 [Hnoi2014]画框
- bzoj3576: [Hnoi2014]江南乐
- bzoj3571: [Hnoi2014]画框
- bzoj3572: [Hnoi2014]世界树
- BZOJ3571: [Hnoi2014]画框
- bzoj3572: [Hnoi2014]世界树
- BZOJ3571[HNOI2014]画框
- [BZOJ3571][HNOI2014]画框
- [BZOJ3572][HNOI2014]世界树
- [BZOJ3572] [Hnoi2014]世界树
- bzoj3571: [Hnoi2014]画框
- BZOJ 3571: [Hnoi2014]画框
- Sofia-SIP辅助文档六
- 如何阅读一份代码?
- 【poj1005】I Think I Need a Houseboat 题解&代码(c++)
- 非常好用的无限轮播
- ActiveX控件加载资源
- JZOJ 3669【HNOI2014】抄卡组
- 错误中学习--ssh整合问题
- Mac系统启动MySQL的federated引擎
- 6.17学习总结 Android Studio去除头部标题
- Spring Cloud构建微服务架构(六)高可用服务注册中心
- Script
- Android 控件架构与自定义控件(四)
- java swing编程学习
- php5.3+apache2.2配置要点