BZOJ3507 [Cqoi2014]通配符匹配 【哈希 + 贪心】
题目
几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户。最常见的通配符有两个,一个
是星号(“”’),可以匹配0个及以上的任意字符:另一个是问号(“?”),可以匹配恰好一个任意字符。
现在需要你编写一个程序,对于给定的文件名列表和一个包含通配符的字符串,判断哪些文件可以被匹配。
输入格式
第一行是一个由小写字母和上述通配符组成的字符串。
第二行包含一个整数n,表示文件个数。
接下来n行,每行为一个仅包含小写字母字符串,表示文件名列表。
输出格式
输出n行,每行为“YES”或“NO”,表示对应文件能否被通配符匹配。
输入样例
*aca?ctc
6
acaacatctc
acatctc
aacacatctc
aggggcaacacctc
aggggcaacatctc
aggggcaacctct
输出样例
YES
YES
YES
YES
YES
NO
提示
对于1 00%的数据
·字符串长度不超过1 00000
· 1 <=n<=100
·通配符个数不超过10
题解
由于通配符很少,我们可以将原串按\(*\)分成若干段,每段为由?隔开的若干个字符串
然后用hash贪心匹配即可
细节极多
最重要的是记得考虑两端是否有\(*\)
码力不足的蒟蒻我已累瘫
还有我丑陋的代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
#define ULL unsigned long long int
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
ULL P[maxn];
char T[maxn];
int tot,L[maxn],n;
vector<ULL> hash[maxn];
vector<int> len[maxn];
int head,tail;
void init(){
P[0] = 1;
for (int i = 1; i <= 100000; i++) P[i] = P[i - 1] * 107;
scanf("%s",T + 1);
n = strlen(T + 1);
if (T[1] == '*') head = true;
if (T[n] == '*') tail = true;
for (int i = 1; i <= n; i++){
if (T[i] == '*') continue;
tot++;
LL h = 0;
for (int j = i; j; j++){
if (j > n || T[j] == '*'){
hash[tot].push_back(h);
len[tot].push_back(j - i);
i = j;
break;
}
if (T[j] == '?'){
hash[tot].push_back(h);
len[tot].push_back(j - i);
h = 0;
i = j + 1;
continue;
}
h = h * 107 + T[j];
}
}
for (int i = 1; i <= tot; i++){
L[i] = len[i].size() - 1;
for (int j = 0; j < len[i].size(); j++){
L[i] += len[i][j];
}
}
/*for (int i = 1; i <= tot; i++,puts(""))
for (int j = 0; j < len[i].size(); j++)
printf("%d ",len[i][j]);*/
}
char s[maxn];
int m;
ULL h[maxn];
bool cmp(int u,int p){
int t = p;
for (int j = 0; j < len[u].size(); j++){
if (t > m) return false;
int r = t + len[u][j] - 1;
if (r > m) return false;
if (hash[u][j] != h[r] - h[t - 1] * P[len[u][j]]) return false;
t = r + 2;
}
return true;
}
void solve(){
int q = read();
while (q--){
scanf("%s",s + 1);
m = strlen(s + 1);
h[0] = 0;
int l = 1,r = m;
for (int i = 1; i <= m; i++) h[i] = h[i - 1] * 107 + s[i];
if (!head){
if (!cmp(1,1)){
puts("NO");
continue;
}
l = L[1] + 1;
}
if (!tail){
if (!cmp(tot,m - L[tot] + 1)){
puts("NO");
continue;
}
r = m - L[tot];
}
//puts("LXT");
/*if (head && !tail && tot == 1){
puts("YES");
continue;
}
if (!head && tail && tot == 1){
puts("YES");
continue;
}*/
int p = l,i,E = tail ? tot : tot - 1;
for (i = head ? 1 : 2; i <= E && p <= r; i++){
if (cmp(i,p)) p += L[i];
else p++,i--;
}
if (i <= E){
puts("NO");
}
else puts("YES");
}
}
int main(){
init();
solve();
return 0;
}
BZOJ3507 [Cqoi2014]通配符匹配 【哈希 + 贪心】的更多相关文章
- BZOJ3507 [Cqoi2014]通配符匹配
题意 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号("*"),可以匹配0个及以上的任意字符:另一个是问号(" ...
- [BZOJ3507][CQOI2014]通配符匹配(DP+Hash)
显然f[i][j]表示S匹配到第i个通配符,T匹配到第j个字符,是否可行. 一次一起转移两个通配符之间的所有字符,Hash判断. 稍微有点细节.常数极大卡时过排名倒数,可能是没自然溢出的原因. #in ...
- [bzoj3507 Cqoi2014]通配符匹配 (hash+DP)
传送门 Solution 显然用哈希233 设\(f[i][j]\)表示第i个通配符和当前第j个字符是否匹配 考虑两种通配符的特性,直接转移即可 Code #include <cstdio> ...
- 【BZOJ3507】通配符匹配(哈希,动态规划)
[BZOJ3507]通配符匹配(哈希,动态规划) 题面 BZOJ 题解 对于匹配唯一存在影响的只有通配符,而\(?\)的影响也并不大,所以唯一需要仔细考虑的是\(*\). 考虑一个\(dp\),设\( ...
- 【BZOJ-3507】通配符匹配 DP + Hash
3507: [Cqoi2014]通配符匹配 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 372 Solved: 156[Submit][Statu ...
- 「题解报告」 P3167 [CQOI2014]通配符匹配
「题解报告」 P3167 [CQOI2014]通配符匹配 思路 *和?显然无法直接匹配,但是可以发现「通配符个数不超过 \(10\) 」,那么我们可以考虑分段匹配. 我们首先把原字符串分成多个以一个通 ...
- bzoj 3507: [Cqoi2014]通配符匹配
Description 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号(“”’),可以匹配0个及以上的任意字符:另一个是问号(“?”),可 ...
- P3167 [CQOI2014]通配符匹配 题解
题目 题目大意 给出一个字符串,其中包含两种通配符 ‘?’和 ‘*’ ,‘?’可以代替一个字符,‘*’可以代替一个字符串(长度可以为0) 然后给出几个字符转,判断能否用给出的字符串表示出来 样例解释 ...
- [CQOI2014]通配符匹配
Description 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号(""'),可以匹配0个及以上的任意字符:另一个 ...
随机推荐
- 解决Error"基础连接已经关闭: 未能为SSL/TLS 安全通道建立信任关系
今天写程序的时候调用到一个第三方的DLL文件,本机调试一切都正常,但是程序不是到服务器以后一直提示一个BUG:"基础连接已经关闭: 未能为SSL/TLS 安全通道建立信任关系". ...
- ssh整合思想 Spring与Hibernate的整合ssh整合相关JAR包下载 .MySQLDialect方言解决无法服务器启动自动update创建表问题
除之前的Spring相关包,还有structs2包外,还需要Hibernate的相关包 首先,Spring整合其他持久化层框架的JAR包 spring-orm-4.2.4.RELEASE.jar ( ...
- Xcode中的Project和Target
新创建工程(如下图e.g.),APP的属性包括了 PROJECT 和 TARGETS 两块内容.且一个工程只有一个 PROJECT,但可以有一个或多个 TARGETS(从苹果的命名上也可以看出,这个 ...
- iOS深拷贝与浅拷贝
概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 如图详解:
- 【转】C++后台开发应该读的书
转载自http://www.cnblogs.com/balloonwj/articles/9094905.html 作者 左雪菲 根据我的经验来谈一谈,先介绍一下我的情况,坐标上海,后台开发(也带团队 ...
- LaTeX中常用数学符号总结
博主一些小小的总结,以后会继续更的. 某个传送门. ⎝⎛•‿•⎞⎠⎝⎛•‿•⎞⎠⎝⎛•‿•⎞⎠ 1.左右一个$: 1+1=2 $1+1=2$ ($3$及以后的都需要$) 2.左右两个$: 1+1=2 ...
- destoon 列表页面增加手动选择排序方式
在mobile/include/mall.inc.php 行60 $order = $MOD['order']; 之前增加 排序方式判断 如果有order参数则$order接受参数,没有就用默认 ...
- Library setup
- virtualbox安装win7系统报错(“FATAL:No bootable medium found!”)
virtualbox属于傻瓜式安装虚拟系统,但博主安装win7系统时,无论怎么调试都还是出现截图所述样式,网上教程很多,但是都不行,其实只有一个根本原因安装的iso镜像不是原生镜像,下载的镜像已经是被 ...
- python-函数的对象、函数嵌套、名称空间和作用域
目录 函数的对象 函数对象的四大功能 引用 当做参数传给一个函数 可以当做函数的返回值 可以当做容器类型的元素 函数的嵌套 函数的嵌套定义 函数的嵌套调用 名称空间与作用域 名称空间 内置名称空间 全 ...