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. Android Android环境安装

    Android环境安装 一.下载: 所需:eclipse.sdk.jdk.adt 参考 工具下载地址:http://www.androiddevtools.cn/ 二安装: 1.eclipse: 选择 ...

  2. 企业sudo权限规划详解 (实测一个堆命令搞定)

    简述问题:         随着公司的服务器越来越多,人员流动性也开始与日俱增,以往管理服务器的陈旧思想应当摒弃,公司需要有 更好更完善的权限体系,经过多轮沟通和协商,公司一致决定重新整理规划权限体系 ...

  3. TigerVNC编译安装

    TigerVNC official site:http://www.linuxfromscratch.org/blfs/view/svn/xsoft/tigervnc.html TigerVNC版本: ...

  4. ubuntu17.04安装flash

    因为用不了软件商店(别问我为什么) 所以手动安装 1 下载文件 在firefox下下载  *****.tar.gz 压缩包 ,并解压(一般目录在 /home 当前用户下的 下载目录下) adobe官网 ...

  5. ASP SQLDATASOURCE

    原文链接:http://blog.csdn.net/dodream/article/details/4887076

  6. [51nod1190]最小公倍数之和V2(莫比乌斯反演)

    题解 传送门 题解 我是真的不明白这玩意儿是怎么跟反演扯上关系的-- 首先 \[ \begin{align} ans &=b\sum_{d|b}{1\over d}\sum_{i=a}^{b} ...

  7. Python第一次写的代码

    #!/bin/bash/env python # -*- coding:utf-8 -*- #function:输出1-10每隔1秒 import time start = 1 flag = True ...

  8. v$sqlarea,v$sql,v$sqltext这三个视图提供的sql语句有什么区别?

    v$sqltext存储的是完整的SQL,SQL被分割 SQL> desc v$sqltextName                                      Null?    ...

  9. Windows Server 2016 IIS10安装URLRewrite 2.0组件方法

    1,打开Regedit> HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ InetStp2,编辑“MajorVersion”并以十进制设置数值数据值为93 ...

  10. NOIP后省选集训前文化课划水记

    划水划了一个多月,文化课没啥长进还他妈累死了...--ghj1222 11.11(NOIP Day2) 师傅开车开得很快,晚上8:00多就到了二狱 晚上听毒瘤班主任swh讲了半节语文,我:黑人问号.j ...