Test of String
1、前言
这是我出的第一套题目,话说感觉有点晚了,还是在向总安排下出的。我被安排的是字符串方面的内容,这应该相对而言是比较小众的知识点吧,但是一样的有作用的,也有很神的题目。所谓是NOIP模拟题,其实只有两道题是在NOIP范围内的,但是要说很难的话,我觉得也不至于(可能是站在出题人的角度上吧)。
因为是第一次出题目,效率确实不怎么高,相比学长出题一天就是一套,我这一套出了快十天了,内容和数据是原创的,但是难免有模板题的感觉(毕竟不能太过头),除了部分出题思路有所参照之外。
2、Tea 喝茶
大概题意: 给出n个字符串,求有多少个字符串中的Q/W/E/R个数超过该字符串的字符个数的1/2。
题解:
由于我们要进行的操作就是查找字符串中的特殊字符,所以最简单有效的方法就是对于每一个字符串的每一个字符进行枚举,统计这个字符串中的Q/W/E/R个数,然后用该个数乘2看是否超过字符串总长度,求和即可。需要注意的是,由于大小写字母均存在,但是不区分,故需要进行两次判断或者进行大小写转化后再统计。时间复杂度为O(n∗len) ,其中len为所有字符串长度的平均值。
但是我们注意到,对于100%的数据,1≤n≤2000,字符串长度≤20000,题目的复杂度很高,一旦程序的常数写得过大,是很容易超时的。
3、Journey 归途
大概题意:给出一个长度为n的带权字符串和长度为m的子字符串,求子字符串是否出现在带权字符串中,且出现位置的最后一位之前的权值和是否超过限制权值,如果没有就输出该权值和。存在x组数据。
题解:
题目表面上似乎是一道图论题,n个节点,m条边,并且还带权值,但是所询问内容令人费解:在图中找到一段路。如果题目要求每个节点只能访问一次,这样当然是简单的,但是由于不限制次数,故可能出现若干个环,并且对于每一条边,每次经过的权值都是不同的!如果直接用无向图来维护的话,基本上是不可能的。所以,我们可以从另外一个角度来考虑:我们将所走的这段路铺平,不将其视为图中遍历,而是看作一个线性数组,而题目要求为在这个数组中找到另一个线性数组。这样,题意就已经很明确了:子串匹配母串。(即大概题意所述)
确定了字符串匹配这个大主题,直接想到的就是暴力枚举,时间复杂度为O(x∗n∗m)。根据题目所给数据范围,这显然是不能通过的。KMP算法可以很好地解决,时间复杂度为O(x∗(n+m))。当然扩展KMP算法也可行。
由于权值的存在以及对其的限制,我们只需要记录字符串中每个字符之前的权值之和,对于第一次成功匹配判断是否大于maxt,如果是的,则说明无法匹配上;相反地,直接输出权值和。
要注意到的是,由于2≤p≤m≤10^5, 1≤t[i]≤10^5,0≤maxt≤∑t×2,故超过int范围是不可避免的,所以需要开long long。
4、Piano 钢琴手
大概题意:给出一个带n个字符的字典,有m个禁用的单词,问能组成多少个不同的长度为m的字符串,不包括p个禁用的单词。如果不存在则输出-1。
题解:
n个字符,组成长度为m的字符串,假设我们无视那k个禁用单词的情况,那么情况为多少呢?其实就是个简单的数学问题,方案数为n^m。其实这样已经可以得到10分了!我们注意到,在数据点7-8中,由于每一个有问题的音乐片段长度和所弹奏长度相等,这样的话每禁止一个,方案数直接减1即可,即答案为n^m−k。
那么对于其他情况的话,不能简单的用公式来计算。首先可以确定的是,我需要构建AC自动机,将题目要表达的意思形象化。因为单词的禁用,不仅影响到其本身,而且只要一段之中有这个单词,就都算不合法,那么我们将这p个禁用的单词放入AC自动机中,设单词的最后一个字符的节点为i,则节点i的所有儿子节点就都不合法了。这也同样意味着,对于两个字符串a和b,如果a是b的前缀,那么禁用b是可以忽略的(想一想,为什么)。如图所示,假设给出一个字符集合为{a,b,c}的字典,禁用单词为:a,bb。则构建的AC自动机如下:

紫色表示插入AC自动机的禁用单词,灰色和紫色部分都是不可选的,而剩下的橙色的个数之和就是方案数了。
然而接下来就是如何计算方案数了。这里建议用简单方便的动态规划,用f[i][j]表示当前长度为i,字符为j的方案数。状态转移也非常简单:
f[i][j]=∑f[i−1][j],k表示能够在AC自动机中走到字符为j的节点的节点。
一切似乎都已经准备就绪,但是我们再来看一眼数据范围,当n=25,m=50时,答案最大可能高达25^50=7.89e+69,所以最后计算的时候,需要进行高精度运算。
5、Happiness 幸福
大概题意:给出n个字符串,找出最长公共子串,要求在每个字符串中都出现至少两次,并且没有重叠。
题解:
首先可以确定的是,单串匹配多串首选后缀数组。相比直接找最长公共子串,这道题附加的条件在于每个字符串内都要出现多次,且不重叠,那么暂时先不管,考虑如何求最长公共子串。
因为需要的是在每个字符串中都出现,我们显然不可能为每一个字符串都开一个后缀数组,这样操作麻烦,又浪费空间。可以考虑将所有的字符串全部连在一起,中间用特殊符号中断以区分。但是题意中写明了所有可见的字符都有可能出现,我们不能保证哪一个特殊符号不会在字符串中出现,所以可以考虑用一个标号数组进行区分,即num[i]表示第i个后缀在第num[i]个字符串中。
利用后缀数组,我们将每个后缀的名次计算出来,然后再计算相邻后缀的最长公共前缀,即height[i]。
现在考虑每个字符串内部需要出现多次的条件。其实在看明白了前面如何衔接不同字符串这个步骤之后,这就很好去写了,即将原来字符串之间的最长公共前缀修改成每个字符串内部的最长公共前缀。求解的过程用二分答案来完成,每次记录所有字符串内部一个位置的最大值和一个位置的最小值,观察差值,求出所有答案的最大值即可。
Test of String的更多相关文章
- 透过WinDBG的视角看String
摘要 : 最近在博客园里面看到有人在讨论 C# String的一些特性. 大部分情况下是从CODING的角度来讨论String. 本人觉得非常好奇, 在运行时态, String是如何与这些特性联系上的 ...
- JavaScript String对象
本编主要介绍String 字符串对象. 目录 1. 介绍:阐述 String 对象的说明以及定义方式. 2. 实例属性:介绍 String 对象的实例属性: length. 3. 实例方法:介绍 St ...
- ElasticSearch 5学习(9)——映射和分析(string类型废弃)
在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...
- [C#] string 与 String,大 S 与小 S 之间没有什么不可言说的秘密
string 与 String,大 S 与小 S 之间没有什么不可言说的秘密 目录 小写 string 与大写 String 声明与初始化 string string 的不可变性 正则 string ...
- js报错: Uncaught RangeError: Invalid string length
在ajax请求后得到的json数据,遍历的时候chrome控制台报这个错误:Uncaught RangeError: Invalid string length,在stackoverflow查找答案时 ...
- c# 字符串连接使用“+”和string.format格式化两种方式
参考文章:http://www.liangshunet.com/ca/201303/218815742.htm 字符串之间的连接常用的两种是:“+”连接.string.format格式化连接.Stri ...
- 【手记】注意BinaryWriter写string的小坑——会在string前加上长度前缀length-prefixed
之前以为BinaryWriter写string会严格按构造时指定的编码(不指定则是无BOM的UTF8)写入string的二进制,如下面的代码: //将字符串"a"写入流,再拿到流的 ...
- JavaScript中String对象的方法介绍
1.字符方法 1.1 charAt() 方法,返回字符串中指定位置的字符. var question = "Do you like JavaScript?"; alert(ques ...
- 在多线程编程中lock(string){...}隐藏的机关
常见误用场景:在订单支付环节中,为了防止用户不小心多次点击支付按钮而导致的订单重复支付问题,我们用 lock(订单号) 来保证对该订单的操作同时只允许一个线程执行. 这样的想法很好,至少比 lock( ...
- BCL中String.Join的实现
在开发中,有时候会遇到需要把一个List对象中的某个字段用一个分隔符拼成一个字符串的情况.比如在SQL语句的in条件中,我们通常需要把List<int>这样的对象转换为“1,2,3”这样的 ...
随机推荐
- android版本对应表
API Level 最初Android版本 Linux内核版本 首次发布日期 后续Android版本 28 9 Unknown 2018-07-02(Beta 3) - 27 8.1 4.10 201 ...
- Mac系统docker初探
最近把工作环境要切到mac中,由于一直想看看docker是怎么回事,以前在win和linux下面都没有用起来,这次在mac中决定试一把,尝试下新的环境部署方式. 安装docker mac中,直接有类似 ...
- Go函数篇
1 定义格式 函数构成代码执行的逻辑结构.在Go语言中,函数的基本组成为:关键字func.函数名.参数列表.返回值.函数体和返回语句. Go 语言函数定义格式如下: func FuncName(/*参 ...
- Maven学习 一 (下载安装)
Maven简介 Apache Maven 是一个软件项目管理工具.基于项目对象模型(project Object Model ,POM)的概念,Maven可用来管理项目的依赖,编译,文档等信息 使用M ...
- Mac下Appnium的Android的UI自动化环境搭建
1. 安装jdk:略 检查是否安装:执行命令java -version admindeMacBook-Pro-2:~ $ java -version java version "1.8.0_ ...
- 我为啥不想用Python
Python这门语言从一开始就是一个玩具语言,它不是给正经程序员用的东西. 运行效率低 Python运行效率很低,这就导致Python中很多库底层实际上是C++.很多时候,自己千方百计优化的结果就不如 ...
- SVG跟随父级DIV自适应
后台返回过来的是这样的SVG标签 <svg width="100%" height="100%" version="1.1" xmln ...
- springboot入门介绍
1. SpringBoot学习之@SpringBootApplication注解 下面是我们经常见到SpringBoot启动类代码: @SpringBootApplicationpublic clas ...
- unity 2d碰撞/ui组件碰撞
首先,ugui的碰撞是可以用Collision2D跟Rigidbody2D实现的(就跟3D碰撞一样).之前试过不可以主要问题正在于Collision2D以及Rigidbody的设置上. 碰撞双方都添加 ...
- Spark源码执行逻辑分析【基于案例SparkPi】
一.案例SparkPi代码 package scala import org.apache.spark.sql.SparkSession import scala.math.random /** Co ...