https://www.luogu.org/problem/P2957

题目描述

The cows enjoy mooing at the barn because their moos echo back, although sometimes not completely. Bessie, ever the excellent secretary, has been recording the exact wording of the moo as it goes out and returns. She is curious as to just how much overlap there is.
Given two lines of input (letters from the set a..z, total length in the range 1..80), each of which has the wording of a moo on it, determine the greatest number of characters of overlap between one string and the other. A string is an overlap between two other strings if it is a prefix of one string and a suffix of the other string.

By way of example, consider two moos:
moyooyoxyzooo
yzoooqyasdfljkamo
The last part of the first string overlaps 'yzooo' with the first part of the second string.
The last part of the second string overlaps 'mo' with the first part of the first string.
The largest overlap is 'yzooo' whose length is 5.

POINTS: 50

 

奶牛们非常享受在牛栏中哞叫,因为她们可以听到她们哞声的回音。虽然有时候并不能完全听到完整的回音。Bessie曾经是一个出色的秘书,所以她精确地纪录了所有的哞叫声及其回声。她很好奇到底两个声音的重复部份有多长。

输入两个字符串(长度为1到80个字母),表示两个哞叫声。你要确定最长的重复部份的长度。两个字符串的重复部份指的是同时是一个字符串的前缀和另一个字符串的后缀的字符串。

我们通过一个例子来理解题目。考虑下面的两个哞声:

moyooyoxyzooo

yzoooqyasdfljkamo

第一个串的最后的部份"yzooo"跟第二个串的第一部份重复。第二个串的最后的部份"mo"跟第一个串的第一部份重复。所以"yzooo"跟"mo"都是这2个串的重复部份。其中,"yzooo"比较长,所以最长的重复部份的长度就是5。

输入描述:

* Lines 1..2: Each line has the text of a moo or its echo

输出描述:

* Line 1: A single line with a single integer that is the length of the longest overlap between the front of one string and end of the other.

示例1

输入

abcxxxxabcxabcd
abcdxabcxxxxabcx

输出


说明

'abcxxxxabcx' is a prefix of the first string and a suffix of the second string.

题目大意

给两个字符串,找出最大重复长度(两个字符串的重复部份指的是同时是一个字符串的前缀和另一个字符串的后缀的字符串)

暴力解法:

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <math.h>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
const int maxn=1e5+;
using namespace std;
//ios::sync_with_stdio(false);
// cin.tie(NULL); int main()
{
string s1,s2;
cin>>s1>>s2;
int len1=s1.size();
int len2=s2.size();
string ss="";
int ans=;
for(int i=;i<=len1;i++)
{
ss+=s1[i];
if(i+>len2)
break;
if(s2.find(ss,len2-(i+))!=string::npos)
ans=i+;
}
ss="";
for(int i=;i<=len2;i++)
{
ss+=s2[i];
if(i+>len1)
break;
if(s1.find(ss,len1-(i+))!=string::npos)
ans=max(ans,i+);
}
cout<<ans<<endl;
}

思路一样,但更加简洁的写法

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <math.h>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
const int maxn=1e5+;
using namespace std;
//ios::sync_with_stdio(false);
// cin.tie(NULL); int main()
{
string s1,s2;
cin>>s1>>s2;
int ans=;
for(int i=;i<=min(s1.size(),s2.size());i++)//比较s1与s2长度,并取最小
{
if(s1.substr(,i)==s2.substr(s2.size()-i,i))//提取子串
ans=max(ans,i);
if(s2.substr(,i)==s1.substr(s1.size()-i,i))
ans=max(ans,i);
}
cout<<ans<<endl;
}

下面是别人的hush做法:

分析

比如两个字符串a、b,因为有可能是a的头和b的尾、b的头和a的尾两种情况,那么我们就处理出a的头、a的尾、b的头、b的尾,然后再for一遍找最大值即可。

对于这两个字符串的头和尾,我们就可以用到字符串hash,front[i]、back[i]分别表示:前i个字符的hash值和后i个字符的hash值,其实就是一个类似于前缀和和后缀和的东西(前缀后缀和与本题无关)。

最后我们再取fronta和backb、frontb、backa分别扫一遍,找出hash值相同的最大位置,就是最长的重复部分。

代码

 #include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define mod 192**817//咳咳
#define ins 11111
using namespace std;
char a[];//字符串a
char b[];//字符串b
int lena,lenb;//两个字符串的长度
int fronta[],backa[];//a的前缀、后缀hash值
int frontb[],backb[];//b的前缀、后缀hash值
int ans;//记录覆盖长度
int maxx;//记录最大覆盖长度
int front_insert_hash(char s[],int len)//计算前缀hash值
{
ll sum=;//初始化hash值
for(int i=;i<len;i++)
sum=(sum*ins+(ll)s[i])%mod;//计算hash值
return sum;//返回hash值
}
int back_insert_hash(char s[],int len)//计算后缀hash值
{
ll sum=;//初始化hash值
int lenn=strlen(s);//lenn是字符串总长度
for(int i=lenn-len;i<lenn;i++)//注意这里的len是从后往前数的第几位
sum=(sum*ins+(ll)s[i])%mod;//计算哈市值
return sum;//返回hash值
}
int main()
{
scanf("%s",a);//读入第一个字符串
scanf("%s",b);//读入第二个字符串
lena=strlen(a);//第一个字符串的长度
lenb=strlen(b);//第二个字符串的长度
for(int i=;i<lena;i++)
fronta[i]=front_insert_hash(a,i);//字符串a的前缀hash值
for(int i=;i<lenb;i++)
backb[i]=back_insert_hash(b,i);//字符串b的后缀hash值
for(int i=;i<lenb;i++)
frontb[i]=front_insert_hash(b,i);//字符串b的前缀hash值
for(int i=;i<lena;i++)
backa[i]=back_insert_hash(a,i);//字符串a的后缀hash值
int minlen=min(lena,lenb);//取最短长度
ans=;//重复长度清0
for(int i=;i<minlen;i++)//a的头和b的尾
if(fronta[i]==backb[i])//hash值相等说明字符子串相同
ans=i;
maxx=max(ans,maxx);//取最大值
ans=;//重复长度清0
for(int i=;i<minlen;i++)//a的尾和b的头
if(frontb[i]==backa[i])//hash值相等说明字符子串相同
ans=i;
maxx=max(ans,maxx);//取最大值
cout<<maxx;//输出最大覆盖长度
return ;
}

这题算是字符串hush板子了吧

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define mod 1777777777
using namespace std;
typedef long long LL;
char s1[],s2[];
int len1,len2;
LL g[];
LL f1[],f2[];
void pre()
{
g[]=;
for(int i=;i<max(len1,len2);i++) g[i]=g[i-]*%mod;
f1[]=s1[]-'a';
for(int i=;i<len1;i++) f1[i]=(f1[i-]*+s1[i]-'a')%mod;
f2[]=s2[]-'a';
for(int i=;i<len2;i++) f2[i]=(f2[i-]*+s2[i]-'a')%mod;
}
LL gethash(LL *f,int l,int r)
{
if(!l) return f[r];
return (f[r]-f[l-]*g[r-l+]%mod+mod)%mod;
}
int main()
{
scanf("%s%s",s1,s2);
len1=strlen(s1);
len2=strlen(s2);
pre();
for(int i=min(len1,len2);i;i--)
{
if(gethash(f1,,i-)==gethash(f2,len2-i,len2-) ) { printf("%d",i); return ; }
if(gethash(f2,,i-)==gethash(f1,len1-i,len1-) ) { printf("%d",i); return ; }
}
printf("");
}

[USACO09OCT]谷仓里的回声Barn Echoes(hush、STL)的更多相关文章

  1. 洛谷 2957 [USACO09OCT]谷仓里的回声Barn Echoes

    题目描述 The cows enjoy mooing at the barn because their moos echo back, although sometimes not complete ...

  2. 洛谷——P2957 [USACO09OCT]谷仓里的回声Barn Echoes

    https://www.luogu.org/problem/show?pid=2957 题目描述 The cows enjoy mooing at the barn because their moo ...

  3. [luoguP2957] [USACO09OCT]谷仓里的回声Barn Echoes(Hash)

    传送门 团队里的hash水题,数据小的不用hash都能过.. 也就是前缀hash,后缀hash,再比较一下就行. ——代码 #include <cstdio> #include <c ...

  4. 3409: [Usaco2009 Oct]Barn Echoes 牛棚回声

    3409: [Usaco2009 Oct]Barn Echoes 牛棚回声 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 57  Solved: 47[ ...

  5. [USACO17JAN]Building a Tall Barn建谷仓

    题目描述 Farmer John is building a brand new, NNN -story barn, with the help of his KKK cows ( 1≤N≤K≤101 ...

  6. [luoguP3606] [USACO17JAN]Building a Tall Barn建谷仓(贪心 + 线段树)

    传送门 把线段都读进来然后排序,先按右端点为第一关键字从小到大排序,后按左端点为第二关键字从小到大排序. 注意不能先按左端点后按右端点排序,否则会出现大包小的情况,如下: —————— ———  — ...

  7. 洛谷P3066 [USACO12DEC]逃跑的Barn (线段树合并)

    题目描述It's milking time at Farmer John's farm, but the cows have all run away! Farmer John needs to ro ...

  8. 洛谷P3066 [USACO12DEC] 逃跑的Barn [左偏树]

    题目传送门 逃跑的Barn 题目描述 It's milking time at Farmer John's farm, but the cows have all run away! Farmer J ...

  9. 洛谷 P5542 [USACO19FEB]Painting The Barn

    题目传送门 解题思路: 二维差分的板子题.题解传送门 AC代码: #include<iostream> #include<cstdio> using namespace std ...

随机推荐

  1. linux下启动mysql提示:Timeout error occurred trying to start MySQL Daemon

    启动 mysqld 时经过很长时间显示 Timeout error occurred trying to start MySQL Daemon. 终端进入 mysql 时显示 ERROR 2002 ( ...

  2. linux_c_udp_example

    udp_server #include <stdlib.h> #include <string.h> #include <unistd.h> #include &l ...

  3. 用ps画一个Gif的小房子(1)

    效果如图: 制作方法: 1.新建200*200的画布:复制一块小房子图片 2.点击窗口-时间轴-勾选帧动画 3.如图所示(我这边是一帧对应一个图层) 4.新建图层-这边要新建24个图层,每个图层对应不 ...

  4. Tensorflow学习教程------代价函数

    Tensorflow学习教程------代价函数   二次代价函数(quadratic cost): 其中,C表示代价函数,x表示样本,y表示实际值,a表示输出值,n表示样本的总数.为简单起见,使用一 ...

  5. python:批量修改文件名批量修改图片尺寸

    批量修改文件名  参考博客:https://www.cnblogs.com/zf-blog/p/7880126.html 功能:批量修改文件名 1 2 3 4 5 6 7 8 9 10 11 12 1 ...

  6. Java基础知识点简记

    此篇主要记录(搬运)的是Java中一些常见概念的理解,大致内容如下 final.finally.finalize的区别 Java的传值或者传引用的理解 重写Override和重载Overload的理解 ...

  7. MySQL实现免密登录和数据库无法启动问题

    1. 进入MySQL安装的文件夹,打开my.ini配置文件,打开方式参考:https://www.cnblogs.com/leslie12956/p/11842956.html 2. 停止MysSQL ...

  8. UVA 11375 高精度Bign类

    求火柴的组成的数字最多能组成多少种数字,典型的递推问题 但是因为结果巨大,要用高精度运算 一开始手写高精度,不仅挫的要死,最后还WA了. 最后学了一下白书上面的bign类,相当方便啊. #includ ...

  9. ZOJ 1454 dp

    Employment Planning Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu S ...

  10. 吴裕雄--天生自然MySQL学习笔记:MySQL 事务

    MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成 ...