题目

题目大意

给出一个字符串,其中包含两种通配符 ‘?’和 ‘*’ ,‘?’可以代替一个字符,‘*’可以代替一个字符串(长度可以为0)

然后给出几个字符转,判断能否用给出的字符串表示出来

样例解释

给出字符串:*aca?ctc

判断字符串 :acaacatctc

此时用 * 代替 aba 用 ?代替了t,所以输出YES

解题思路

dp + hash

用hash预处理出字符串的前缀和, 方便判断两端字符是否相同

假设 给出字符串 为str1,  要判断的字符串为 str2

f[i][j]表示 第i个通配符与 要str2的前i个字符 匹配是否可行

当第i个通配符是 * 时特殊判断:

因为 * 可以匹配任意长度的字符串,所以 f[i][j] |=f[i][j-1] (如果匹配到 j-1,那让*再匹配一个,一定可行)

然后枚举str2的每个字符,下标为j,

如果f[i][j]可行,继续判断 给出的字符串 中不是通配符(已经固定)的部分是否能匹配,进行转移

注意

1、因为结尾没有通配符,所以在 str1 结尾加上一个 ‘?’, 在每个str2结尾加上任意一个字符,便于处理结尾部分、

2、如果第i个通配符是 * 应将f[i+1][rb] 赋值为 true,(应为*可以是长度为0的,具体看代码注释)

惊喜

这题与洛谷 P2536 [AHOI2005]病毒检测 基本一样(要统计个数,改了一下数据范围) 一份代码,两道紫题~~~

代码&注释

#include <bits/stdc++.h>
using namespace std;
#define ul unsigned long long
const ul p = 666, N = 100000;
ul sx[N+5], sy[N+5], s[N+5];
int len, lenn, w[12], num, t;
char ch[N+5], cc[N+5];
bool f[12][N+5]; // f[i][j] 表示第i个通配符匹配以j结尾的字符(串)
int main(){
s[0] = 1; for (int i = 1; i <= N; i++) s[i] = s[i-1] * p;
scanf ("%s", ch + 1); len = strlen (ch + 1); ch[++len] = '?'; //在末尾加上一个 ?处理结尾部分
for (int i = 1; i <= len; i++) {
sx[i] = sx[i-1] * p + ch[i]; //预处理出 hash 前缀和
if (ch[i] == '*' or ch[i] == '?') w[++num] = i; //记录通配符的下标
}
scanf ("%d", &t);
while (t--) {
scanf ("%s", cc + 1); lenn= strlen (cc + 1);
cc[++lenn] = '!'; //在末尾加上一个 字符处理结尾部分
for (int i = 1; i <= lenn; i++) sy[i] = sy[i-1] * p + cc[i]; //预处理出 hash 前缀和
memset (f, 0, sizeof (f));
f[0][0] = 1; //初始化
for (int i = 0; i <= num; i++) {
if (ch[w[i]] == '*') for (int j = 1; j <= lenn; j++) f[i][j] |= f[i][j-1]; //是 * 特殊处理
for (int j = 0; j <= lenn; j++) {
if (!f[i][j]) continue;
int la = w[i] + 1, ra = w[i+1] - 1, lb = j + 1, rb = j + w[i+1] - w[i] - 1; //计算出两段的左右端点
if (sx[ra] - sx[la-1] * s[ra-la+1] == sy[rb] - sy[lb-1] * s[rb-lb+1]){ //判断两段是否相同
if (ch[w[i+1]] == '?') f[i+1][rb+1] = 1;
else f[i+1][rb] = 1; //注意:如果是 * ,应将f[i+1][rb]赋值为1而不是f[i+1][rb+1] (*可以匹配长度为0的字符串)
}
}
}
if (f[num][lenn]) puts ("YES");
else puts ("NO");
}
return 0;
}

  

P3167 [CQOI2014]通配符匹配 题解的更多相关文章

  1. 「题解报告」 P3167 [CQOI2014]通配符匹配

    「题解报告」 P3167 [CQOI2014]通配符匹配 思路 *和?显然无法直接匹配,但是可以发现「通配符个数不超过 \(10\) 」,那么我们可以考虑分段匹配. 我们首先把原字符串分成多个以一个通 ...

  2. P3167 [CQOI2014]通配符匹配

    吐槽 本来是去写AC自动机的,然后发现数据范围每个串100000,有100个串(???),连塞进trie树里都塞不进去,玩个鬼的AC自动机啊,tag不要乱打啊 最后拿字符串hash+爆搜一发搜过去了. ...

  3. BZOJ3507 [Cqoi2014]通配符匹配

    题意 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号("*"),可以匹配0个及以上的任意字符:另一个是问号(" ...

  4. BZOJ3507 [Cqoi2014]通配符匹配 【哈希 + 贪心】

    题目 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个 是星号(""'),可以匹配0个及以上的任意字符:另一个是问号(&quo ...

  5. [CQOI2014]通配符匹配

    Description 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号(""'),可以匹配0个及以上的任意字符:另一个 ...

  6. bzoj 3507: [Cqoi2014]通配符匹配

    Description 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号(“”’),可以匹配0个及以上的任意字符:另一个是问号(“?”),可 ...

  7. 【bzoj3570】 Cqoi2014—通配符匹配

    http://www.lydsy.com/JudgeOnline/problem.php?id=3507 (题目链接) 题意 给出一个主串,里面有些通配符,'*'可以代替任意字符串或者消失,'?'可以 ...

  8. [BZOJ3507][CQOI2014]通配符匹配(DP+Hash)

    显然f[i][j]表示S匹配到第i个通配符,T匹配到第j个字符,是否可行. 一次一起转移两个通配符之间的所有字符,Hash判断. 稍微有点细节.常数极大卡时过排名倒数,可能是没自然溢出的原因. #in ...

  9. [bzoj3507 Cqoi2014]通配符匹配 (hash+DP)

    传送门 Solution 显然用哈希233 设\(f[i][j]\)表示第i个通配符和当前第j个字符是否匹配 考虑两种通配符的特性,直接转移即可 Code #include <cstdio> ...

随机推荐

  1. Android 4学习(6):概述 - 深入了解Android Activity

    参考:<Professional Android 4 Application Development> 深入了解Android Activity 每一个Android Activity都对 ...

  2. HotSpotVM创建过程(JNI_CreateJavaVM)详解

    来自:<Java Performance>第3章 JVM Overview The HotSpot VM's implementation of the JNI_CreateJavaVM ...

  3. java 多线程系列基础篇(三)之start()和run()的区别

    概要 Thread类包含start()和run()方法,它们的区别是什么?本章将对此作出解答. start() 和 run()的区别说明 start() : 它的作用是启动一个新线程,新线程会执行相应 ...

  4. Ok6410裸机驱动学习(三)C语言内嵌汇编

    1.C语言内嵌汇编使用方法 C内嵌汇编以关键字”_asm_或asm开始,下辖4个部分,各部分之间用“:”分开,第一部分是必须写的,后面3个部分可以省略,但是分号:不能省略 优化后的代码 2.汇编程序框 ...

  5. 【266】增加bash文件的执行权限

    正常需要通过[bash pass.sh]来执行文件,但是可以通过增加bash文件的执行权限实现通过[./pass.sh]或者[pass.sh]来执行文件. 方法:通过chmod来增加权限,下面四种方法 ...

  6. 关于handler的再次讨论

    主要有两个问题,post方法和sendmessage方法有什么不同? 同一个handler对象发送的message只能发送给自己吗? 问题1: post方法,对于Handler的Post方式来说,它会 ...

  7. day18-事务与连接池 3.jdbc中事务操作介绍

    那么我们都是通过程序操作数据库.所以要了解jdbc下怎样对事务操作.jdbc如何操作事务? 自动事务false那就不开了呗相当于开启事务. package cn.itcast.transaction; ...

  8. clearfix的用法(转)

    clearfix的用法 (2013-12-31 10:41:24) 标签: clearfix 清除浮动 clearboth height zoom 分类: 网页制作 如果有一个DIV作为外部容器,内部 ...

  9. ECMAScript 定义类、对象

    使用预定义对象只是面向对象语言的能力的一部分,它真正强大之处在于能够创建自己专用的类和对象. ECMAScript 拥有很多创建对象或类的方法. 工厂方式 原始的方式 因为对象的属性可以在对象创建后动 ...

  10. php学习笔记-POST和GET的区别

    POST和GET都可以用来提交数据. POST方法提交的数据在浏览器的地址栏是不可见的,当然利用一些工具是可以看到的,而GET方法提交的数据在地址栏是可见的.两者比较,POST更安全一点. POST方 ...