http://www.lydsy.com/JudgeOnline/problem.php?id=3574

我们发现如果所有的字符串都有*,那么只需要比较他们的“前缀”和“后缀”相同即可。“前缀”指第一个*前的字符串,“后缀”指最后一个*后的字符串

如果存在一个字符串没有*,那么要求其他串都能跟这个串匹配,用哈希即可

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<iostream>
  4. #include<fstream>
  5. #include<algorithm>
  6. #include<cstring>
  7. #include<string>
  8. #include<cmath>
  9. #include<queue>
  10. #include<stack>
  11. #include<map>
  12. #include<utility>
  13. #include<set>
  14. #include<bitset>
  15. #include<vector>
  16. #include<functional>
  17. #include<deque>
  18. #include<cctype>
  19. #include<climits>
  20. #include<complex>
  21. #include<cassert>
  22. //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
  23.  
  24. using namespace std;
  25.  
  26. typedef long long LL;
  27. typedef unsigned long long ULL;
  28. typedef double DB;
  29. typedef pair<int,int> PII;
  30. typedef pair<DB,DB> PDD;
  31. typedef complex<DB> CP;
  32. typedef vector<int> VI;
  33.  
  34. #define mmst(a,v) memset(a,v,sizeof(a))
  35. #define mmcy(a,b) memcpy(a,b,sizeof(a))
  36. #define fill(a,l,r,v) fill(a+l,a+r+1,v)
  37. #define re(i,a,b) for(i=(a);i<=(b);i++)
  38. #define red(i,a,b) for(i=(a);i>=(b);i--)
  39. #define fi first
  40. #define se second
  41. #define mp(a,b) make_pair(a,b)
  42. #define pb(a) push_back(a)
  43. #define SF scanf
  44. #define PF printf
  45. #define two(k) (1<<(k))
  46. #define SZ(x) (int(x.size()))
  47. #define all(x) (x).begin(),(x).end()
  48. #define ire(i,v,x) for(i=0,v=i<SZ(x)?x[i]:0;i<SZ(x);v=x[++i])
  49.  
  50. template<class T>inline T sqr(T x){return x*x;}
  51. template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
  52. template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}
  53.  
  54. inline int sgn(DB x){if(abs(x)<1e-)return ;return(x>)?:-;}
  55. const DB Pi=acos(-1.0);
  56.  
  57. int gint()
  58. {
  59. int res=;bool neg=;char z;
  60. for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
  61. if(z==EOF)return ;
  62. if(z=='-'){neg=;z=getchar();}
  63. for(;z!=EOF && isdigit(z);res=res*+z-'',z=getchar());
  64. return (neg)?-res:res;
  65. }
  66. LL gll()
  67. {
  68. LL res=;bool neg=;char z;
  69. for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
  70. if(z==EOF)return ;
  71. if(z=='-'){neg=;z=getchar();}
  72. for(;z!=EOF && isdigit(z);res=res*+z-'',z=getchar());
  73. return (neg)?-res:res;
  74. }
  75.  
  76. const int maxn=;
  77. const int sumlen=;
  78.  
  79. int n;
  80. char mem[sumlen];int now;
  81. int len[maxn],from[maxn],to[maxn];
  82. int mark[maxn],com,nowlen,maxlen;
  83.  
  84. #define P 991
  85. ULL power[sumlen];
  86. ULL sum[sumlen];
  87. void read()
  88. {
  89. int i,j;
  90. n=gint();
  91. now=;
  92. com=-;
  93. maxlen=;
  94. re(i,,n)
  95. {
  96. from[i]=now+;
  97. cin>>mem+now+;
  98. len[i]=strlen(mem+now+);
  99. to[i]=from[i]+len[i]-;
  100. now=to[i];
  101. mark[i]=;
  102. re(j,from[i],to[i])if(mem[j]=='*'){mark[i]=;break;}
  103. if(!mark[i])com=i;
  104. upmax(maxlen,len[i]);
  105. }
  106. power[]=;
  107. while(nowlen<maxlen)power[nowlen+]=power[nowlen]*P,nowlen++;
  108. re(i,,now)sum[i]=sum[i-]*P+mem[i];
  109. }
  110.  
  111. ULL gethash(int l,int r){return sum[r]-sum[l-]*power[r-l+];}
  112.  
  113. int ch[maxn];
  114. char RT[sumlen];
  115.  
  116. int check(int a,int b)
  117. {
  118. int head=from[b];
  119. for(int l=from[a],r;l<=to[a];l=r+)
  120. {
  121. while(mem[l]=='*' && l<=to[a]) l++;
  122. if(l>to[a])break;
  123. for(r=l;r+<=to[a] && mem[r+]!='*';r++);
  124. ULL RIG=gethash(l,r);
  125. while(head+(r-l+)-<=to[b] && gethash(head,head+(r-l+)-)!=RIG) head++;
  126. if(head+(r-l+)->to[b])return ;
  127. head+=r-l+;
  128. }
  129. if(mem[from[a]]!='*')
  130. {
  131. int i,l=from[a],r;
  132. for(r=l;r+<=to[a] && mem[r+]!='*';r++);
  133. re(i,l,r)if(mem[i]!=mem[from[b]+i-l])return ;
  134. }
  135. if(mem[to[a]]!='*')
  136. {
  137. int i,l,r=to[a];
  138. for(l=r;l->=from[a] && mem[l-]!='*';l--);
  139. re(i,l,r)if(mem[i]!=mem[to[b]-(r-i)])return ;
  140. }
  141. return ;
  142. }
  143.  
  144. int check()
  145. {
  146. if(com!=-)
  147. {
  148. int i;
  149. re(i,,n)
  150. {
  151. if(!mark[i] && (len[i]!=len[com] || gethash(from[i],to[i])!=gethash(from[com],to[com])))return ;
  152. if(mark[i] && !check(i,com))return ;
  153. }
  154. return ;
  155. }
  156. else
  157. {
  158. int i,j,p=-;
  159. re(i,,n)
  160. {
  161. for(ch[i]=;ch[i]+<=len[i] && mem[from[i]+ch[i]]!='*';ch[i]++);
  162. if(p==- || ch[p]<ch[i])p=i;
  163. }
  164. re(i,,ch[p])RT[i]=mem[from[p]+i-];
  165. re(i,,n)re(j,,ch[i])if(RT[j]!=mem[from[i]+j-])return ;
  166. p=-;
  167. re(i,,n)
  168. {
  169. for(ch[i]=;ch[i]+<=len[i] && mem[to[i]-ch[i]]!='*';ch[i]++);
  170. if(p==- || ch[p]<ch[i])p=i;
  171. }
  172. re(i,,ch[p])RT[i]=mem[to[p]-i+];
  173. re(i,,n)re(j,,ch[i])if(RT[j]!=mem[to[i]-j+])return ;
  174. }
  175. return ;
  176. }
  177.  
  178. int main()
  179. {
  180. freopen("hs.in","r",stdin);
  181. freopen("hs.out","w",stdout);
  182. int T=gint();
  183. while(T--)
  184. {
  185. read();
  186. PF("%c\n",check()?'Y':'N');
  187. }
  188. return ;
  189. }

bzoj3574[Hnoi2014]抄卡组的更多相关文章

  1. BZOJ3574 HNOI2014抄卡组(哈希)

    容易发现通配符中间的部分可以任意匹配,会造成的无法匹配的仅仅是前后缀,前缀和后缀可以分别独立处理.如果字符串均有通配符,只需要按前/后缀长度排序然后暴力匹配就可以了. 问题在于存在无通配符的字符串.显 ...

  2. luogu P3234 [HNOI2014]抄卡组

    传送门 nmdwsm 自己看吧,不想写了qwq 垃圾代码如下 和题解完全不一样 #define LL long long #define uLL unsigned long long #define ...

  3. 【LG3234】[HNOI2014]抄卡组

    题面 题解 分三种情况: 若所有串都没有通配符,直接哈希比较即可. 若所有串都有通配符, 把无通配符的前缀 和 无通配符的后缀哈希后比较即可. 中间部分由于通配符的存在,一定可以使所有串匹配. 若部分 ...

  4. [HNOI2014]抄卡组

    [Luogu3234] [LOJ2208] 题解及代码 锻炼哈希码力的一道题 , 具体细节见代码 #include<cstdio> #include<cstring> #inc ...

  5. 洛谷P3234 抄卡组 [HNOI2014] 字符串hash

    正解:字符串hash 解题报告: 传送门! 字符串hash是字符串匹配中很常见的一个方法,原理也很好懂,这里就不做太多阐述辣有时间放到hash笔记里面去QAQ 题意不说了挺好理解的,自带一句话概括好评 ...

  6. 【HNOI2014】抄卡组

    题面 题解 如果所有的字符串都有通配符,那么只要比较不含通配符的前缀和后缀就可以了. 否则一定有一个串没有通配符.找出这个字符串,然后将所有串与这个串匹配,通配符将\(B\)分成一段一段在\(A\)上 ...

  7. 【LOJ6254】最优卡组 堆(模拟搜索)

    [LOJ6254]最优卡组 题面 题解:常用的用堆模拟搜索套路(当然也可以二分).先将每个卡包里的卡从大到小排序,然后将所有卡包按(最大值-次大值)从小到大排序,并提前处理掉只有一张卡的卡包. 我们将 ...

  8. HearthBuddy卡组

    偶数萨 手打两天已上传说,各位加油  欧洲牧羊人 ### 火元素换艾雅# 职业:萨满祭司# 模式:狂野模式## 2x (2) 图腾魔像        # 2x (2) 大漩涡传送门   # 2x (2 ...

  9. 服务器&阵列卡&组raid 5

    清除raid信息后,机器将会读不到系统, 后面若进一步操作处理, raid信息有可能会被初始化掉,那么硬盘数据就有可能会被清空, 导致数据丢失, 否则如果只是清除raid信息,重做raid是可以还原系 ...

随机推荐

  1. [C++] [算法] KMP算法

    KMP串匹配算法是一个经典的算法. 传统BF算法是传统的字符串匹配算法.很好理解.叶实现.但时间复杂度太高. 本文将从字符串模式字符串被称为.为了匹配字符串被称为主弦. KMP配时能够少移动从串的位置 ...

  2. 500 OOPS: vsftpd: refusing to run with writable root inside chroot()解决方法

    vsftpd.conf配置文件如下: [root@rusky ~]# cat /etc/vsftpd/vsftpd.conf | grep -v "#" anonymous_ena ...

  3. 编写高效SQL最佳实践

    编写高效 SQL 语句的最佳实践 秦玮, 高级软件工程师, IBM 王广成, 软件工程师, IBM 王韵婷, 高级软件工程师, IBM 简介: 本文列举了一些在编写 SQL 查询语句时可能导致 DB2 ...

  4. jdbc_odbc SQLserver 驱动安装及测试

    有2次被问到同一个问题,尽管博客园是.net的园子,我还是分享下吧.PS:我现在做的.net,以前学过点java.献丑了. ------------------ 原始邮件 -------------- ...

  5. tableView Crash

    转自:http://blog.csdn.net/hamasn/article/details/8613593 Assertion failure in -[UITableView _configure ...

  6. hello,boke

    我一名学习软件工程金融服务工程的学生,简单来说就是学习计算机类的,对于自己的介绍,从平时生活中来说吧,我一直处于一种很中规中矩的生活状态里,平时玩玩手机.追追剧.和室友一起去图书馆自习,考前拼命复习两 ...

  7. HDU 4632 CF 245H 区间DP(回文)

    先说HDU 4632这道题,因为比较简单,题意就是给你一个字符串,然后给你一个区间,叫你输出区间内所有的回文子序列,注意是回文子序列,不是回文字串. 用dp[i][j]表示区间[i,j]内的回文子序列 ...

  8. 学习C++——只声明忘记定义了

    #include <iostream> #include <list> #include <string> using namespace std; class E ...

  9. 10分钟 教你学会Linux/Unix下的vi文本编辑器

    10分钟 教你学会Linux/Unix下的vi文本编辑器 vi编辑器是Unix/Linux系统管理员必须学会使用的编辑器.看了不少关于vi的资料,终于得到这个总结.不敢独享,和你们共享. 首先,记住v ...

  10. 数据库备份工具mysqldump重要参数详解

    1. --single-transaction InnoDB 表在备份时,通常启用选项 --single-transaction 来保证备份的一致性,实际上它的工作原理是设定本次会话的隔离级别为:RE ...