KMP--君住长江头,我住长江尾,日日思君不见君,共饮长江水
POJ 3461: Oulipo
题意:
求出第一个串在第二个串中的出现次数...
分析:
KMP板子题...
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
using namespace std;
//眉眼如初,岁月如故 const int maxn=+; int cas,lens,lenp,nxt[maxn]; char s[maxn],p[maxn]; inline void getnxt(void){
nxt[]=nxt[]=;int k;
for(int i=;i<lenp;i++){
k=nxt[i];
while(k&&p[k+]!=p[i+])
k=nxt[k];
if(p[k+]==p[i+])
nxt[i+]=k+;
else
nxt[i+]=;
}
} inline void kmp(void){
int ans=,posp=,poss=;
while(poss<=lens){
if(p[posp]==s[poss])
posp++,poss++;
else if(posp==)
poss++;
else
posp=nxt[posp-]+;
if(posp==lenp+)
ans++,posp=nxt[posp-]+;
}
printf("%d\n",ans);
} signed main(void){
scanf("%d",&cas);
while(cas--){
memset(nxt,,sizeof(nxt));
scanf("%s%s",p+,s+);
lenp=strlen(p+);lens=strlen(s+);
getnxt();kmp();
}
return ;
}//Cap ou pas cap. Pas cap.
POJ 2406: Power Strings
题意:
求出每个串的最短循环节出现次数...
分析:
此题两种解法...然而本质上是一样的...
No.1 Hash
对于一个串其前缀A和后缀B相同并且有重叠,并且len%strlen(str-B)==0,那么str-B一定是循环节...所以我们可以用hash水过...
No.2 next数组...
然而更机智的做法是next数组...
代码:
No.1 Hash
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define int long long
using namespace std;
const int maxn=+,MOD=;
char str[maxn];
int len,ans;
unsigned int hash[maxn],pow[maxn];
signed main(void){
pow[]=(long long);
for(int i=;i<maxn;i++)
pow[i]=(pow[i-]*)%MOD;
while(scanf("%s",str+)&&str[]!='.'){
len=strlen(str+),hash[]=,ans=;
for(int i=;i<=len;i++)
hash[i]=(hash[i-]*%MOD+str[i]-'a'+)%MOD;
for(int i=;i<len;i++){
if(len%(len-i)==){
if(hash[i]%MOD==(hash[len]-hash[len-i]*pow[i]%MOD+MOD)%MOD){
ans=len/(len-i);
}
}
}
cout<<ans<<endl;
}
return ;
}
No.2 next数组
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
using namespace std;
//眉眼如初,岁月如故 const int maxn=+; int len,nxt[maxn]; char str[maxn]; inline void getnxt(void){
nxt[]=nxt[]=;int k;
for(int i=;i<len;i++){
k=nxt[i];
while(k&&str[k+]!=str[i+])
k=nxt[k];
if(str[k+]==str[i+])
nxt[i+]=k+;
else
nxt[i+]=;
}
} signed main(void){
while(scanf("%s",str+)&&str[]!='.'){
len=strlen(str+);getnxt();
if(len%(len-nxt[len])==)
printf("%d\n",len/(len-nxt[len]));
else
puts("");
}
return ;
}//Cap ou pas cap. Pas cap.
POJ 2752: Seek the Name, Seek the Fame
题意:
输出所有s的合法前缀,合法前缀的定义为前缀等于后缀...
分析:
不断nxt...
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
using namespace std;
//眉眼如初,岁月如故 const int maxn=+; int len,tail,nxt[maxn],stk[maxn]; char str[maxn]; inline void getnxt(void){
nxt[]=nxt[]=;int k;
for(int i=;i<len;i++){
k=nxt[i];
while(k&&str[k+]!=str[i+])
k=nxt[k];
if(str[k+]==str[i+])
nxt[i+]=k+;
else
nxt[i+]=;
}
} signed main(void){
while(scanf("%s",str+)!=EOF){
len=strlen(str+);getnxt();tail=;stk[++tail]=len;
while(nxt[len])
stk[++tail]=nxt[len],len=nxt[len];
for(int i=tail;i>=;i--)
printf("%d ",stk[i]);
puts("");
}
return ;
}//Cap ou pas cap. Pas cap.
POJ 3167: Cow Patterns
题意:
给出两个串,如果a和b匹配当且仅当ab中的每个对应位置的数字rank1和rank2相同,rank1代表当前元素前面小于他的元素个数,rank2代表当前元素前面等于他的元素个数,求出匹配串和模式串的匹配位置(开头位置)
分析:
KMP…裸的KMP…就是计算一下rank就好…
因为数字不会超过25,所以直接暴力求rank就好…
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
using namespace std;
const int maxn=+,maxk=+,maxs=+;
int n,k,s,a[][maxn],nxt[maxk],num[][maxn][maxs],vis[maxk];
inline int rank1(int len,int en,int id){
int st=en-len,ans=;
for(int i=;i<a[id][en];i++)
ans+=num[id][en][i]-num[id][st][i];
return ans;
}
inline int rank2(int len,int en,int id){
return num[id][en][a[id][en]]-num[id][en-len][a[id][en]];
}
inline void getnext(void){
nxt[]=nxt[]=;int p;
for(int i=;i<k;i++){
p=nxt[i];int a=rank1(p+,p+,),b=rank1(p+,i+,),c=rank2(p+,p+,),d=rank2(p+,i+,);
while(p&&(a!=b||c!=d))
p=nxt[p],a=rank1(p+,p+,),b=rank1(p+,i+,),c=rank2(p+,p+,),d=rank2(p+,i+,);
if(rank1(p+,p+,)==rank1(p+,i+,)&&rank2(p+,p+,)==rank2(p+,i+,))
nxt[i+]=p+;
else
nxt[i+]=;
}
}
inline void kmp(void){
int posa=,posb=,ans=,stk[maxn];
while(posa<=n){
if(rank1(posb,posa,)==rank1(posb,posb,)&&rank2(posb,posa,)==rank2(posb,posb,))
posa++,posb++;
else if(posb==)
posa++;
else
posb=nxt[posb-]+;
if(posb==k+)
stk[++ans]=posa-k,posb=nxt[posb-]+;
}
cout<<ans<<endl;
for(int i=;i<=ans;i++)
cout<<stk[i]<<endl;
}
signed main(void){
scanf("%d%d%d",&n,&k,&s);memset(num,,sizeof(num));
for(int i=;i<=n;i++)
scanf("%d",&a[][i]),num[][i][a[][i]]=;
memset(vis,,sizeof(vis));
for(int i=;i<=n;i++)
for(int j=;j<=s;j++)
num[][i][j]+=num[][i-][j];
for(int i=;i<=k;i++)
scanf("%d",&a[][i]),num[][i][a[][i]]=;
for(int i=;i<=k;i++)
for(int j=;j<=s;j++)
num[][i][j]+=num[][i-][j];
getnext();kmp();
return ;
}
By NeighThorn
KMP--君住长江头,我住长江尾,日日思君不见君,共饮长江水的更多相关文章
- 【POJ3461】【KMP】Oulipo
Description The French author Georges Perec (1936–1982) once wrote a book, La disparition, without t ...
- gj11 多线程、多进程和线程池编程
11.1 python中的GIL # coding=utf-8 # gil global interpreter lock (cpython) # python中一个线程对应于c语言中的一个线程 # ...
- HTML5文本
1.重要文本.斜体文本 粗体:<strong></strong> 粗体:<b></b> 斜体:<em></em> 斜体:< ...
- 多线程复习 Rlock ,Condition,Semaphore
#对于io操作来说,多线程和多进程性能差别不大 #1.通过Thread类实例化 import time import threading def get_detail_html(url): print ...
- NO.006-2018.02.11《卜算子·我住长江头》宋代:李之仪
卜算子·我住长江头_古诗文网(bǔ) 卜算子·我住长江头 宋代:李之仪 我住长江头,君住长江尾.日日思君不见君,共饮长江水. 我居住在长江上游,你居住在长江下游. 天天想念你却见不到你,共同喝着长江的 ...
- 界面实例--旋转的3d立方体
好吧,这里直接编辑源码并不允许设置css和js……毕竟会有危险……那直接放代码吧 <!DOCTYPE html> <html> <head> <meta ch ...
- python Condition
import threading # 必须要使用condition的例子 # class XiaoAi(threading.Thread):# def __init__(self, lock):# s ...
- 第十章:Python高级编程-多线程、多进程和线程池编程
第十章:Python高级编程-多线程.多进程和线程池编程 Python3高级核心技术97讲 笔记 目录 第十章:Python高级编程-多线程.多进程和线程池编程 10.1 Python中的GIL 10 ...
- IO和socket编程
五一假期结束了,突然想到3周前去上班的路上看到槐花开的正好.放假也没能采些做槐花糕,到下周肯定就老了.一年就开一次的东西,比如牡丹,花期也就一周.而花开之时,玫瑰和月季无法与之相比.明日黄花蝶也愁.想 ...
随机推荐
- es6展开运算符
数组的展开合并 现在有两个数组[1, 2, 3, 4]和[5, 6, 7],想要将两个函数拼接成一个新的函数. //es5的写法 let arr1 = [1, 2, 3, 4]; let arr2 = ...
- sigqueue与kill详解及实例
/*********************************************************************************************** 相关函 ...
- JS - Object.create(prototype)方法
用Object.create(prototype)方法创建一个对象,这个对象的原型将指向这个传入的prototype参数
- Docker学习笔记--2 镜像的创建
如果我们需要在Docker环境下部署tomcat.redis.mysql.nginx.php等应用服务环境,有下面三种方法: 1,根据系统镜像创建Docker容器,这时容器就相当于是一个虚拟机,进入容 ...
- 为什么90%的IT人员都不适合做老大?
什么是格局? 格局就是能够很好的平衡短期利益和长期利益. 过分注重短期利益的人必然会失去长期利益,到头来一定会很普通. 例如:跳槽不断,可能短期薪资会增长,但长期来看后劲可能会不足,未来发展空间会变窄 ...
- 自动化运维工具——ansible系列命令
ansible-galaxy 连接 https://galaxy.ansible.com 下载相应的roles,此网站是Ansible爱好者将日常使用较好的playbooks打包上传,其他人可以免费下 ...
- 22.VUE学习之-replice删除当前评论条数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- spring boot 设置tomcat post参数限制
今天传图片,用的base64字符串,POST方法,前端传送的时候总是莫名其妙的崩溃,去网上搜了半天,以为是文件大小被限制了,但是我这个是字符串接收,不是文件接收,于是又继续搜,原来post本身没有参数 ...
- python3 爬取汽车之家所有车型数据操作步骤(更新版)
题记: 互联网上关于使用python3去爬取汽车之家的汽车数据(主要是汽车基本参数,配置参数,颜色参数,内饰参数)的教程已经非常多了,但大体的方案分两种: 1.解析出汽车之家某个车型的网页,然后正则表 ...
- 动态规划:HDU1248-钱币兑换问题
解题心得: (青蛙跳台阶:有n阶台阶,青蛙可以一次跳一阶也可以一次跳两阶,问总共有多好中跳法) 1.之前把这个问题的思路弄错了,以为是递推,就像青蛙跳台阶,用斐波那契求解.但是用斐波那契肯定会超范围. ...