String Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2706    Accepted Submission(s): 1140

Problem Description
Give you a string with length N, you can generate N strings by left shifts. For example let consider the string “SKYLONG”, we can generate seven strings:
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.

 
Input
  Each line contains one line the string S with length N (N <= 1000000) formed by lower case letters.
 
Output
Output four integers separated by one space, lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), the string’s times in the N generated strings, lexicographically last string’s Rank (if there are multiple answers, choose the smallest one), and its times also.
 
Sample Input
abcder
aaaaaa
ababab
 
Sample Output
1 1 6 1
1 6 1 6
1 3 2 3
 
Author
WhereIsHeroFrom
 
Source

题目链接: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+最大/最小表示)的更多相关文章

  1. HDU 3374 String Problem(KMP+最大(最小)表示)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:给出一个字符串,依次左移一个单位形成一堆字符串,求其字典序最小和最大的字符串需要左移多 ...

  2. HDU 3374 String Problem (KMP+最大最小表示)

    KMP,在有循环节的前提下: 循环节 t = len-next[len], 个数num = len/(len-next[len]);个人理解,如果有循环节,循环节长度必定小于等于len/2, 换句话说 ...

  3. hdu 3374 String Problem(kmp+最小表示法)

    Problem Description Give you a string with length N, you can generate N strings by left shifts. For ...

  4. HDU 3374 String Problem(最大最小表示+KMP)题解

    题意:给你一个字符串,这个字符串可以这样操作:把第一个字符放到最后一个形成一个新的字符串,记原式Rank为1,每操作一步Rank+1,问你这样操作得出的最小字典序的字符串的Rank和这样的字符串有几个 ...

  5. HDU 3374 String Problem (KMP+最大最小表示)

    HDU 3374 String Problem (KMP+最大最小表示) String Problem Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  6. HDU - 3374 String Problem (kmp求循环节+最大最小表示法)

    做一个高产的菜鸡 传送门:HDU - 3374 题意:多组输入,给你一个字符串,求它最小和最大表示法出现的位置和次数. 题解:刚刚学会最大最小表示法,amazing.. 次数就是最小循环节循环的次数. ...

  7. hdu 3374 String Problem(最小表示法+最大表示法+kmp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题意:给出一个字符串问这个字符串最小表示的最小位置在哪,还有有几个最小表示的串.最大表示的位置在 ...

  8. HDU 3374 String Problem (KMP+最小最大表示)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3374 [题目大意] 给出一个字符串,求出最小和最大表示是从哪一位开始的,并且输出数量. [题解] ...

  9. hdu 3374 String Problem (kmp+最大最小表示法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:输出最大和最小的是从哪一位开始的,同时输出最小循环节的个数. 这里简单介绍对字符串最小 ...

随机推荐

  1. 一、HTML和CSS基础--网页布局--如何用css进行网页布局

    什么叫做布局? 又称版式布局,是网页UI设计师将有限的视觉元素进行有机的排列组合. 网页设计的特点 网页可以自适应宽度 网页的高度理论上可以无限延长 网页分栏 分栏又称为分列,常见的布局分为:一列布局 ...

  2. Zabbix报告无交换内存主机 Lack of free swap space on xxxxx

    [root@xx ~]# free -m total used free shared buffers cached Mem: 3832 3488 343 0 267 2389 -/+ buffers ...

  3. tar split命令

    转自:http://www.cnblogs.com/xiaouisme/archive/2011/05/25/2057435.html tar是文件打包工具,split是文件分割工具,在邮件中发送附件 ...

  4. Mysql or Mongodb LBS快速实现方案

    http://www.wubiao.info/470 前两篇文章: 查找附近的xxx 球面距离以及Geohash方案探讨 (http://www.wubiao.info/372) 微信.陌陌 架构方案 ...

  5. PHP数组的使用方法小结

    数组就是一组数据的集合,把一系列数据组织起来,形成一个可操作的整体.数组的每个实体都包含两项:键和值. 一.什么是数组数组就是一组数据的集合,把一系列数据组织起来,形成一个可操作的整体.数组的每个实体 ...

  6. ffmpeg 中添加264支持

    转自:http://blog.sina.com.cn/s/blog_513f4e8401011yuq.html ffmpeg 中带有264的解码,没有编码,需要添加x264: 参考百度上的“windo ...

  7. 布局文件中fill_parent、match_parent和wrap_content有什么区别?

    fill_parent 宽度或者高度 布满整个屏幕从Android 2.2开始fill_parent改名为match_parent.wrap_content布局元素将根据内容更改大小.

  8. Java中的Timer和TimerTask在Android中的用法(转)

    转自:http://blog.csdn.net/zuolongsnail/article/details/8168689 在开发中我们有时会有这样的需求,即在固定的每隔一段时间执行某一个任务.比如UI ...

  9. C#中使用ListView动态添加数据不闪烁并显示当前插入值

    首先,自定义一个类ListViewNF,继承自 System.Windows.Forms.ListView class ListViewNF : System.Windows.Forms.ListVi ...

  10. android 完美退出所有Activity的demo

    项目地址:https://github.com/libill/myapplication 利用android的wheel和参考android完美退出程序做出来的demo,结束掉所有打开的Activit ...