HDU 5442——Favorite Donut——————【最大表示法+kmp | 后缀数组】
Favorite Donut
Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1702 Accepted Submission(s): 430
Once Lulu eats a part of the donut, she must continue to eat its uneaten adjacent part until all parts are eaten. Therefore, she has to eat either clockwise or counter-clockwise after her first bite, and there are 2n ways to eat the ring donut of n parts. For example, Lulu has 6 ways to eat a ring donut abc: abc,bca,cab,acb,bac,cba. Lulu likes eating the sweetest part first, so she actually prefer the way of the greatest lexicographic order. If there are two or more lexicographic maxima, then she will prefer the way whose starting part has the minimum index in clockwise order. If two ways start at the same part, then she will prefer eating the donut in clockwise order. Please compute the way to eat the donut she likes most.
For each test case, the first line contains one integer n,n≤20000, which represents how many parts the ring donut has. The next line contains a string consisted of n lowercase alphabets representing the ring donut.
aaab
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+500;
char str[maxn],sp[maxn],revs[maxn],rvsp[maxn];
char tx[3*maxn];
int f[maxn];
int get_max(char *s){ //最大(最小)表示法得到的是正序遍历最大(最小)字典序开始位置。
int i=0,j=1,k=0;
int len=strlen(s);
while(i<len&&j<len){
if(k==len){
break;
}
if(s[(i+k)%len]<s[(j+k)%len]){
i=i+k+1>j? i+k+1:j+1;
k=0;
}else if(s[(i+k)%len]>s[(j+k)%len]){
j=j+k+1>i? j+k+1:i+1;
k=0;
}else{
k++;
}
}
return min(i,j);
}
void get_s_p(char *sr,char *s,int st,int len){ //提取字符串
for(int i=st,k=0;k<len;i++,k++){
sr[i-st]=s[i%len];
}
sr[len]='\0';
}
void rev(char *s,int len){ //反转
for(int i=len-1;i>=0;i--){
revs[len-1-i]=s[i];
} revs[len]='\0';
} void getfail(char *P,int *F){
int m=strlen(P);
F[0]=F[1]=0; int j;
for(int i=1;i<m;i++){
j=F[i];
while(j&&P[i]!=P[j]) j=F[j];
F[i+1]=P[i]==P[j]?j+1:0;
}
}
int kmp(char *T,char *P){
int n=strlen(T),m=strlen(P);
int j=0;
int ret=0;
for(int i=0;i<n-1;i++){
while(j&&P[j]!=T[i]) j=f[j];
if(P[j]==T[i]) j++;
if(j==m){
ret=max(ret,i-m+1); //对于反转后的串,需得到最大位置
j=f[j];
}
}
return ret;
}
int main(){
int t , n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
scanf("%s",str);
rev(str,n); int ckw=get_max(str);
get_s_p(sp,str,ckw,n); int ctckw=get_max(revs);
get_s_p(rvsp,revs,ctckw,n); strcpy(tx,revs);
strcat(tx,revs); getfail(rvsp,f);
int ans=kmp(tx,rvsp); //在反转后的串中的位置
ans=n-1-ans; //转化为原串中的位置
int d=strcmp(sp,rvsp);
if(d>0){
printf("%d 0\n",ckw+1);
}else if(d<0){
printf("%d 1\n",ans+1);
}else{
if(ckw<=ans){
printf("%d 0\n",ckw+1);
}else{
printf("%d 1\n",ans+1);
}
}
}
return 0;
}
HDU 5442——Favorite Donut——————【最大表示法+kmp | 后缀数组】的更多相关文章
- hdu 5442 Favorite Donut 最大表示法+kmp
题目链接 给你一个字符串, 然后把他想象成一个环. 从某一个地方断开,然后逆时针或顺时针, 都可以形成一个字符串, 求字典序最大的那种. 输出断开位置以及是顺时针还是逆时针. 如果两个一样, 输出位置 ...
- 【HDU - 5442】Favorite Donut 【最大表示法+KMP/后缀数组】
题意 给出一个长度为n的环状由小写字母组成的序列,请找出从何处断开,顺时针还是逆时针,使得字典序最大.如果两个字符串的字典序一样大,那么它会选择下下标最小的那个.如果某个点顺时针逆时针产生的字典序大小 ...
- Hdu 5442 Favorite Donut (2015 ACM/ICPC Asia Regional Changchun Online 最大最小表示法 + KMP)
题目链接: Hdu 5442 Favorite Donut 题目描述: 给出一个文本串,找出顺时针或者逆时针循环旋转后,字典序最大的那个字符串,字典序最大的字符串如果有多个,就输出下标最小的那个,如果 ...
- HDU 5442 Favorite Donut(暴力 or 后缀数组 or 最大表示法)
http://acm.hdu.edu.cn/showproblem.php?pid=5442 题意:给出一串字符串,它是循环的,现在要选定一个起点,使得该字符串字典序最大(顺时针和逆时针均可),如果有 ...
- hdu 5442 Favorite Donut 后缀数组
Favorite Donut Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid ...
- luogu 2463 [SDOI2008]Sandy的卡片 kmp || 后缀数组 n个串的最长公共子串
题目链接 Description 给出\(n\)个序列.找出这\(n\)个序列的最长相同子串. 在这里,相同定义为:两个子串长度相同且一个串的全部元素加上一个数就会变成另一个串. 思路 参考:hzwe ...
- POJ2406 Power Strings(KMP,后缀数组)
这题可以用后缀数组,KMP方法做 后缀数组做法开始想不出来,看的题解,方法是枚举串长len的约数k,看lcp(suffix(0), suffix(k))的长度是否为n- k ,若为真则len / k即 ...
- POJ 2406 KMP/后缀数组
题目链接:http://poj.org/problem?id=2406 题意:给定一个字符串,求由一个子串循环n次后可得到原串,输出n[即输出字符串的最大循环次数] 思路一:KMP求最小循环机,然后就 ...
- POJ-3450 Corporate Identity (KMP+后缀数组)
Description Beside other services, ACM helps companies to clearly state their “corporate identity”, ...
随机推荐
- 在ubuntu 14.04 编译android 2.3.1 错误解决办法
首先必须降低gcc版本: sudo apt-get install gcc-4.4sudo apt-get install g++-4.4sudo rm -rf /usr/bin/gcc /usr/b ...
- c# 生成xml,xsi不能生成问题
C# 生成xml,xsi不能生成问题 一.简单了解xsi及其其他属性: xsi:schemaLocation用于声明了目标名称空间的模式文档,属性的值由一个URI引用对组成,两个URI之间以空白符分 ...
- [CentOS7] 设置语言环境
博主想要将英文环境(en_US.UTF-8)改为中文环境(zh_CN.UTF-8),有两种解决方法 一.临时解决方法 使用LANG=“zh_CN.UTF-8”,这个命令来实现,不过在重新登录的时候又会 ...
- php写的非常简单的文件浏览器
php写的非常简单的一个文件浏览器,仅供参考. <?php /** * php文件浏览程序函数 showDir() * * $dirName 输入目录路径,默认php文件一级目录,不需输入: * ...
- B - EXCEL排序(sort+结构体)
Excel可以对一组纪录按任意指定列排序.现请你编写程序实现类似功能. Input测试输入包含若干测试用例.每个测试用例的第1行包含两个整数 N (<=100000) 和 C,其中 N 是纪录的 ...
- vue框架搭建的详细步骤(一)
在这里我们先快速的搭建一个vue的脚手架: (1).在安装vue的环境之前,安装NodeJS环境是必须的.可以使用node -v指令检查,需要保证安装了4.0版本以上的nodeJS环境. 没有安装的话 ...
- CAT部署集成文档
1. 下载编译 1.1 下载源码 首先,到项目的git网页下载整个项目: https://github.com/dianping/cat 1.2 打包安装 接着就是进入这个项目的目录,运行打包安装命 ...
- POI精确设置Excel的行高和列宽
EXCEL的行高度和列宽度单位是不一样的. 1,EXCEL列高度的单位是磅,Apache POI的行高度单位是缇(twip): 1英寸=72磅=25.4毫米=1440缇1磅=0.353毫米=20缇 P ...
- CF431C k-Tree dp
Quite recently a creative student Lesha had a lecture on trees. After the lecture Lesha was inspired ...
- 树莓派编译安装 EMQ 服务器
前言 EMQ 是一款开源的物联网 MQTT 消息服务器,使用 Erlang/OTP 语言平台设计,在 DIY 智能家居时可以作为网关,前几天摸索了一下在树莓派中安装 EMQ 的方法,记录一下. 步骤 ...