Favorite Donut

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1702    Accepted Submission(s): 430

Problem Description
Lulu has a sweet tooth. Her favorite food is ring donut. Everyday she buys a ring donut from the same bakery. A ring donut is consists of n parts. Every part has its own sugariness that can be expressed by a letter from a to z (from low to high), and a ring donut can be expressed by a string whose i-th character represents the sugariness of the i−th part in clockwise order. Note that z is the sweetest, and two parts are equally sweet if they have the same sugariness.

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.

 
Input
First line contain one integer T,T≤20, which means the number of test case.

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.

 
Output
You should print one line for each test case, consisted of two integers, which represents the starting point (from 1 to n) and the direction (0 for clockwise and 1 for counterclockwise).
 
Sample Input
2
4
abab
4
aaab
 
Sample Output
2 0
4 0
 
Source
 
 
题目大意:顺时针或逆时针遍历字符串,让求最大字典序。如果最大字典序唯一,那么输出得到最大字典序的位置及遍历顺序。如果不唯一,那么位置小的优先,如果位置也相同,那么顺时针优先。结果输出位置及遍历顺序。顺时针为0,逆时针为1。
 
吐槽:自己被自己玩死了。数据范围自己开小了,题目是2W,自己yy的1W,错到死  WA。
 
解题思路:对于顺时针得到最大字典序的最小下标,可以用最大表示法直接得到。对于逆时针的最小下标,我们首先将原字符串反转,然后用最大表示法得到下标,但是得到的这个下标,并不是原串逆序得到最大字典序的最小下标,而是最大的。所以我们将反转后的串复制在另外一个空串中,再在尾部连上一个反转后的串,将这个长度为2n的串作为文本串。然后我们在反转后的串中提取出在原串中逆序最大字典序的串作为模式串,然后用kmp匹配,这时候匹配需要得到最大的匹配位置(由于是反转后的串,所以最大即在原串中最小)。最后先比较正序和逆序得到的字符串是否相同,不同取大的遍历顺序;相同则比较位置大小,小的或等的顺时针优先。
 
#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 | 后缀数组】的更多相关文章

  1. hdu 5442 Favorite Donut 最大表示法+kmp

    题目链接 给你一个字符串, 然后把他想象成一个环. 从某一个地方断开,然后逆时针或顺时针, 都可以形成一个字符串, 求字典序最大的那种. 输出断开位置以及是顺时针还是逆时针. 如果两个一样, 输出位置 ...

  2. 【HDU - 5442】Favorite Donut 【最大表示法+KMP/后缀数组】

    题意 给出一个长度为n的环状由小写字母组成的序列,请找出从何处断开,顺时针还是逆时针,使得字典序最大.如果两个字符串的字典序一样大,那么它会选择下下标最小的那个.如果某个点顺时针逆时针产生的字典序大小 ...

  3. Hdu 5442 Favorite Donut (2015 ACM/ICPC Asia Regional Changchun Online 最大最小表示法 + KMP)

    题目链接: Hdu 5442 Favorite Donut 题目描述: 给出一个文本串,找出顺时针或者逆时针循环旋转后,字典序最大的那个字符串,字典序最大的字符串如果有多个,就输出下标最小的那个,如果 ...

  4. HDU 5442 Favorite Donut(暴力 or 后缀数组 or 最大表示法)

    http://acm.hdu.edu.cn/showproblem.php?pid=5442 题意:给出一串字符串,它是循环的,现在要选定一个起点,使得该字符串字典序最大(顺时针和逆时针均可),如果有 ...

  5. hdu 5442 Favorite Donut 后缀数组

    Favorite Donut Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid ...

  6. luogu 2463 [SDOI2008]Sandy的卡片 kmp || 后缀数组 n个串的最长公共子串

    题目链接 Description 给出\(n\)个序列.找出这\(n\)个序列的最长相同子串. 在这里,相同定义为:两个子串长度相同且一个串的全部元素加上一个数就会变成另一个串. 思路 参考:hzwe ...

  7. POJ2406 Power Strings(KMP,后缀数组)

    这题可以用后缀数组,KMP方法做 后缀数组做法开始想不出来,看的题解,方法是枚举串长len的约数k,看lcp(suffix(0), suffix(k))的长度是否为n- k ,若为真则len / k即 ...

  8. POJ 2406 KMP/后缀数组

    题目链接:http://poj.org/problem?id=2406 题意:给定一个字符串,求由一个子串循环n次后可得到原串,输出n[即输出字符串的最大循环次数] 思路一:KMP求最小循环机,然后就 ...

  9. POJ-3450 Corporate Identity (KMP+后缀数组)

    Description Beside other services, ACM helps companies to clearly state their “corporate identity”, ...

随机推荐

  1. ubuntu 删除mysql

    UBUNTU 彻底删除 MYSQL 然后重装 MYSQL 删除 mysql sudo apt-get autoremove --purge mysql-server-5.0sudo apt-get r ...

  2. JetBrains WebStorm 如何从GitHub上克隆的代码

    工作中经常会遇到要从GitHub上拉代码,详细操作记录如下: 绑定账号 1.File->Settings->Version Control->Github 成功后会出现下面的这个账户 ...

  3. web安全-xss攻击

    web安全问题 xss攻击 1.html标签 html内容的转义 escapeHtml str = str.replace(/&/g,'&amp'); str = str.replac ...

  4. CI框架源码学习笔记3——Log.php

    上一节说完了Common.php,然而跟代码打交道总是免不了日志记录,所以这一节我们说说Log.php文件. 先看看类里面的几个属性, protected $_log_path;  日志路径 prot ...

  5. CF912E Prime Gift 数学

    Opposite to Grisha's nice behavior, Oleg, though he has an entire year at his disposal, didn't manag ...

  6. 黑马集合学习 自定义ArrayList01

    package demo; import java.util.Arrays; public class MyArrayList<T> { Object[] t; int size; pri ...

  7. xshell一直连接中断 守护进程

    last指令 重新登录使用last指令查看登录情况 pts的理解 who:查看目前有谁在线 pts是所谓的伪终端或虚拟终端,具体表现就是你打开一个终端,这个终端就叫pts/0,如果你再打开一个终端,这 ...

  8. 使用git将本地代码提交到码云上去

    码云为开源中国基于git的代码网络托管平台,将代码托管.开发与项目管理工具融为一体.今天第一次将自己的web项目代码上传至码云,过程中遇到一些问题,此处进行总结与过程的演示:当我们在码云上创建好项目后 ...

  9. jvm与tomcat启动优化配置

    JVM 优化 Java 的内存模型分为: Young,年轻代(易被 GC).Young 区被划分为三部分,Eden 区和两个大小严格相同的 Survivor 区,其中 Survivor 区间中,某一时 ...

  10. JavaScript权威指南--闭包讲解摘记

    不积跬步无以至千里,不积小流无以成江河. 关于闭包的解释,在<JavaScript权威指南>中讲的很透彻了.今天看了书中的一个段讲解,更加深了对闭包的理解,特此记下,以备查阅. 在同一个作 ...