acdream 1683 村民的怪癖(KMP,经典变形)
Problem Description
娜娜费劲九牛二虎之力终于把糖果吃完了(说好的吃不完呢?骗人,口亨~),于是,缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷,娜娜甚异之。复前行,欲穷其林。林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田美池桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。(摘自《桃花源记》)
娜娜与村民交流了好久才发现这里的人们给孩子的命名方式很奇怪,首先村民们的名字都是用专门的符号来记录,正好是26个符号,于是娜娜就把它们替换成‘a’~‘z’,然后首先把爸爸的名字作为孩子的姓,妈妈的名字作为孩子的名。这时候肯定有人会问,不是独生子女怎么办?很简单~取拼接好的名字的前缀与后缀相同的部分从短到长依次作为孩子的姓名,啥,不够?那就不许你再生孩子!
不过由于桃花村民与世隔绝太久了,以致于他们总是无法正确判断一对夫妻最多能生多少个孩子,于是就把这个任务交给你了。
P.S. 若用S[1,n]表示一个长度为n的字符串,那么S[1,i](1<=i<=n)表示S的一个前缀,S[j,n](1<=j<=n)表示S的一个后缀。具体看样例解释
Input
多组数据,首先是一个正整数t(t<=20),表示数据的组数
对于每一组数据,包含两个只由'a'~'z'组成的不含空格的字符串S1,S2,分别代表丈夫的姓名以及妻子的姓名。(1<=|S1|,|S2|<=100000)
Output
Sample Input
2
ababc ababa
aaaaa aaa
Sample Output
3
8
Hint
对于样例1,把丈夫和妻子的姓名拼接在一起是ababcababa,可以作为孩子的姓名的是a、aba、ababcababa,故最多生育3个孩子
对于样例2,把丈夫和妻子的姓名拼接在一起是aaaaaaaa,可以作为孩子的姓名的是a、aa、aaa、aaaa、aaaaa、aaaaaa、aaaaaaa、aaaaaaaa,故最多生育8个孩子
题意:
给两个串a和b,合并他们成为1个串s,即s=a+b。如果串s的前缀与后缀匹配了,只要长度不同,都算可以算作一个独立的匹配,问有多少这样的匹配(注意前缀与后缀是可以重叠的)?
假设s="abcdefg",等长前缀和后缀有:len=7的abcdefg和abcdefg,len=6的abcdef和bcdefg,len=5的abcde和cdefg.....直到1个的a和g。
思路:
KMP的经典变形,这里仅有一个模式串而已,没原串。只需要对模式串求next数组就可以得到结果了,时间是O(n)。具体看下例:
假如有两串:ababc ababa
合并后变为:ababcababa
求next数组之后变为:
第1 2 3 4 5 6 7 8 9 10个
0 0 1 2 0 1 2 3 4 3
a b a b c a b a b a
找最长的合法串:第10个字符为a,而next[10]表示s[10-3+1,10]等同于s[1,3]这两个小串是相同的,也就是一个合法的名字,而且该名字是最长的(也就是长度9,因为10个的话就是自身了,毋庸置疑)。如下两个红色串:
ababcababa
接下来找次长的合法串:第next[10]个(即第3个,是a)的next应该是next[3],即1。也就是说s[1]=s[3]。而这个串在上一步才提到,是等于尾串的!看上面尾部红色的字符,aba=前部的aba,而前部aba中的后部a又等于前部的a。这说明了又是一个合法的名字。
ababcababa
接下来到next[1]=0了,也就没有再多可以匹配的了, 仅剩1个字符无法跟别人匹配。
这是模式串next数组本身的特点。细心点就可以发现。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=; void get_next(string &m, vector<int> &next) //求next数组
{
next.push_back(-); //一开始是-1
int i=, j=-;
while(i<m.size())
{
if(j==- || m[i]==m[j]) //j在原串上, i在模式串上
{
next.push_back(++j);
++i;
}
else j = next[j];
}
} int cal(string &m)
{
vector<int> next;
get_next(m, next);
int len=m.size();
if(next[len]==len-) return len; //全都一样的
int i=next[len], cnt=;
while(i>) //只要next[i]>0就是一个匹配
{
cnt++;
i=next[i];//注意串s是以0开头的,而next是以1开头的。
}
return cnt+; //本身就是一个符合条件的串
} int main()
{
freopen("e://input.txt", "r", stdin);
int t;
cin>>t;
string s1,s2;
while(t--)
{
cin>>s1>>s2;
s1+=s2;
printf("%d\n",cal(s1));
}
return ;
}
AC代码
acdream 1683 村民的怪癖(KMP,经典变形)的更多相关文章
- D - 娜娜梦游仙境系列——村民的怪癖
D - 娜娜梦游仙境系列——村民的怪癖 Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Othe ...
- HDU 5918 SequenceI (2016 CCPC长春站 KMP模版变形)
这个题目的数据应该是比较弱的,赛场上的时候我们暴力也过了,而且我的kmp居然比暴力还要慢-- 这个变形并不难,跳着选数,把漏掉的位置补上就可以了. 代码如下: #include<iostream ...
- UVA 10537 The Toll! Revisited 过路费(最短路,经典变形)
题意:给一个无向图,要从起点s运送一批货物到达终点e,每个点代表城镇/乡村,经过城镇需要留下(num+19)/20的货物,而经过乡村只需要1货物即可.现在如果要让p货物到达e,那么从起点出发最少要准备 ...
- CSU - 1581 Clock Pictures (KMP的变形题,难想到)
题目链接: http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1581 题目意思:告诉你现在有两个钟,现在两个钟上面都有n个指针,告诉你指针的位置, ...
- HDU 1711 Number Sequence (数字KMP,变形)
题意: 在一个序列中找到一个连续的子序列,返回其开始位置. 思路: 每个数字当成1个字符,长的序列是原串,短的序列是模式串,求next数组后进行匹配. #include <iostream> ...
- Divide Two Integers——二分法的经典变形
Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...
- HDU - 4333 :Revolving Digits (扩展KMP经典题,问旋转后有多少个不同的数字小于它本身,等于它本身,大于它本身。)
One day Silence is interested in revolving the digits of a positive integer. In the revolving operat ...
- HDU 2594 kmp算法变形
Simpsons’ Hidden Talents Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- kmp练习
kmp板子如下, 失配数组不优化的话, $f_i$就表示子串[0...i]前后缀最大匹配长度 int main() { scanf("%s%s", t, p); int n = s ...
随机推荐
- POJ 1151 Atlantis(经典的线段树扫描线,求矩阵面积并)
求矩阵的面积并 采用的是区间更新 #include <iostream> #include <stdio.h> #include <string.h> #inclu ...
- ExtJs布局之tabPanel
<!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...
- Spring MVC 教程,快速入门,深入分析(转)
原文地址:http://elf8848.iteye.com/blog/875830/
- 欧拉工程第52题:Permuted multiples
题目链接 题目: 125874和它的二倍,251748, 包含着同样的数字,只是顺序不同. 找出最小的正整数x,使得 2x, 3x, 4x, 5x, 和6x都包含同样的数字. 这个题目相对比较简单 暴 ...
- servlet中中文乱码问题
在web项目中经常回碰到中文乱码的问题,特此整理一下,有不足的地方,希望大家纠正. 1从前台往后台传数据,.以get方式发送请求,发送的参数不乱,但是后台接收到参数乱码 在Tomcat的server. ...
- 拥有更好性能的requesAnimationFrame(Better Performance with requestAnimationFrame)
介绍: 这篇文章讨论的是你可以(也应该)学习通过使用requestAnimationFrame API,而不是使用之前的setInterval/setTimeout方法,来提高动画的性能:如何使用re ...
- Clearing Floats清除浮动--clearfix的不同方法的使用概述
清除浮动早已是一个前端开发人员必学的一课.毫无疑问,多年来,我们已经接触过多种清除浮动的方法,现在“clearfix methods”越来越被大家熟知.在深入剖析“clearfix”的多种用法之前,我 ...
- HTML5之拖拽(兼容IE和非IE)
前世:项目中需要拖动div,然后和某个div进行位置交换,这不是关键,关键是还要保存位置,然后在下次打开的时候按照保存的位置显示.还好本人功力深厚,一下子就想到了用localStorage来保存,事实 ...
- Java应用发布后,需要关注的7个性能指标
在某个重大发布之后,都需要记录相应的指标,本文介绍了最重要的几个 Java 性能指标,包括响应时间和平均负载等.为理解应用程序在生产环境中如何运行,就需要遵循一些 Java 性能指标. 在以前,当软件 ...
- UML系列01之 UML用例图
UML,全称是Unified Modeling Language,中文是"统一建模语言".通俗点说,UML是一种创建模型的语言. UML是在开发阶段,说明,可视化,构建和书写一个面 ...