HDU 3374 String Problem(KMP+最大/最小表示)
String Problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2706 Accepted Submission(s): 1140
String Rank
SKYLONG 1
KYLONGS 2
YLONGSK 3
LONGSKY 4
ONGSKYL 5
NGSKYLO 6
GSKYLON 7
and lexicographically first of them is GSKYLON, lexicographically last is YLONGSK, both of them appear only once.
Your task is easy, calculate the lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), its times, lexicographically last string’s Rank (if there are multiple answers, choose the smallest one), and its times also.
题目链接:HDU 3374
求最小与最大字典序的所需左移次数和出现次数,左移次数用两倍的s来匹配,在计数的时候把第一次匹配成功的开头位置记录下来即可,计数过程中i要小于len*2-1,比如abcde拿来当主串扩展两倍后变成abcdeabcde,其实中间一共左移所生成的串只有len-1个即到edbde就结束了,因此不能再去匹配最后一个e,不然像abcde本身拿去匹配这个串就出现了两次了……,代码写起来比较麻烦,顺便复习一下好久没敲了的KMP搜索函数。
代码:
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<bitset>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int N=1000010;
char s[N],fir[N],las[N],temp[N<<1];
int nxta[N],nxtb[N];
int len,L;
void init()
{
CLR(s,0);
CLR(fir,0);
CLR(las,0);
CLR(nxta,0);
CLR(nxtb,0);
CLR(temp,0);
}
void getnext(char s[],int nxt[])
{
int j=0,k=nxt[0]=-1;
len=strlen(s);
while (j<len)
{
if(k==-1||s[j]==s[k])
nxt[++j]=++k;
else
k=nxt[k];
}
}
int minp()
{
int i=0,j=1,k=0;
while (i<len&&j<len&&k<len)
{
int t=s[(i+k)%len]-s[(j+k)%len];
if(!t)
++k;
else
{
if(t>0)
i+=(k+1);
else
j+=(k+1);
if(i==j)
++j;
k=0;
}
}
return i<j?i:j;
}
int maxp()
{
int i=0,j=1,k=0;
while (i<len&&j<len&&k<len)
{
int t=s[(i+k)%len]-s[(j+k)%len];
if(!t)
++k;
else
{
if(t>0)
j+=(k+1);//要把这里i、j互换即可,其他不变
else
i+=(k+1);
if(i==j)
++j;
k=0;
}
}
return i<j?i:j;
}
pii kmp_count(char s[],char p[],int nxt[])
{
int i=0,j=0;
pii r;
r.first=-1,r.second=0;
while (i<L-1&&j<len)
{
if(s[i]==p[j]||j==-1)
{
++i;
++j;
}
else
j=nxt[j];
if(j==len)
{
if(r.first==-1)//只记录第一次的出现位置
r.first=i-j+1;
++r.second;
j=nxt[j];
}
}
return r;
}
int main(void)
{
int i,j,k;
while (~scanf("%s",s))
{
len=strlen(s);
L=len<<1;
int minm=minp();
int maxm=maxp();
strcpy(temp,s);
strcat(temp,s);
int cnt;
for (cnt=0,i=minm; cnt<len; ++i,++cnt)
fir[cnt]=temp[i];
for (cnt=0,i=maxm; cnt<len; ++i,++cnt)
las[cnt]=temp[i];
getnext(fir,nxta);
getnext(las,nxtb);
pii a=kmp_count(temp,fir,nxta);
pii b=kmp_count(temp,las,nxtb);
printf("%d %d %d %d\n",a.first,a.second,b.first,b.second);
init();
}
return 0;
}
HDU 3374 String Problem(KMP+最大/最小表示)的更多相关文章
- HDU 3374 String Problem(KMP+最大(最小)表示)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:给出一个字符串,依次左移一个单位形成一堆字符串,求其字典序最小和最大的字符串需要左移多 ...
- HDU 3374 String Problem (KMP+最大最小表示)
KMP,在有循环节的前提下: 循环节 t = len-next[len], 个数num = len/(len-next[len]);个人理解,如果有循环节,循环节长度必定小于等于len/2, 换句话说 ...
- hdu 3374 String Problem(kmp+最小表示法)
Problem Description Give you a string with length N, you can generate N strings by left shifts. For ...
- HDU 3374 String Problem(最大最小表示+KMP)题解
题意:给你一个字符串,这个字符串可以这样操作:把第一个字符放到最后一个形成一个新的字符串,记原式Rank为1,每操作一步Rank+1,问你这样操作得出的最小字典序的字符串的Rank和这样的字符串有几个 ...
- HDU 3374 String Problem (KMP+最大最小表示)
HDU 3374 String Problem (KMP+最大最小表示) String Problem Time Limit: 2000/1000 MS (Java/Others) Memory ...
- HDU - 3374 String Problem (kmp求循环节+最大最小表示法)
做一个高产的菜鸡 传送门:HDU - 3374 题意:多组输入,给你一个字符串,求它最小和最大表示法出现的位置和次数. 题解:刚刚学会最大最小表示法,amazing.. 次数就是最小循环节循环的次数. ...
- hdu 3374 String Problem(最小表示法+最大表示法+kmp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题意:给出一个字符串问这个字符串最小表示的最小位置在哪,还有有几个最小表示的串.最大表示的位置在 ...
- HDU 3374 String Problem (KMP+最小最大表示)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3374 [题目大意] 给出一个字符串,求出最小和最大表示是从哪一位开始的,并且输出数量. [题解] ...
- hdu 3374 String Problem (kmp+最大最小表示法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:输出最大和最小的是从哪一位开始的,同时输出最小循环节的个数. 这里简单介绍对字符串最小 ...
随机推荐
- CentOS 5.8/6.7若干优化
CentOS系统安装之后并不能立即投入生产环境使用,往往需要先经过我们运维人员的优化才行.在此讲解几点关于Linux系统安装后的基础优化操作.注意:本次优化都是基于CentOS(5.8/6.7). 下 ...
- Linux底下的第一个C程序
首先保证你的Linux底下安装了GCC,假如没有安装GCC的话请参考: http://www.cnblogs.com/aspirant/p/3544398.html 假如输入 gcc -v 不再是co ...
- sizeof(class)
//#define _REENTRANT //#define _POSIX_C_SOURCE #include <iostream> #include <string> #in ...
- PowerDesigner12逆向生成oracle数据表时,错误解决
1.用PowerDesigner12建模,在Database—>Generate Database (或者用Ctrl+G快捷键)来生产sql语句,却提示“Generation aborted d ...
- php session跨页面传递 session值丢失问题
.session_start();应该尽量放置到页面的顶部: .如果php.ini里面没有配置 session Autostart的话,每次会话之前,都得手动开启session:session_sta ...
- hdu 4006 优先队列 2011大连赛区网络赛F **
签到题都要想一会 #include<cstdio> #include<iostream> #include<algorithm> #include<cstri ...
- loj 1004(dp)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25830‘ 思路:类似与数塔问题,自底向上处理,输入的时候稍微注意一 ...
- 电赛总结(四)——波形发生芯片总结之AD9854
一.特性参数 ·300M内部时钟频率 ·可进行频移键控(FSK),二元相移键控(BPSK),相移键控(PSK),脉冲调频(CHIRP),振幅调制(AM)操作 ·正交的双通道12位D/A转换器 ·超高速 ...
- intersection
用来找到两个rdd的交集,注意,最终的new rdd的分区数量取决于两个rdd中的最大分区数量. 测试一下: val data1 = sc.parallelize(1 to 20,1) val dat ...
- hdu 5762 Teacher Bo 曼哈顿路径
Teacher Bo Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Tota ...