Favorite Donut

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

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

解题:后缀自动机

 #include <bits/stdc++.h>
using namespace std;
const int maxn = ;
struct SAM {
struct node {
int son[],f,len;
void init() {
f = -;
len = ;
memset(son,-,sizeof son);
}
} sn[maxn<<];
int tot,last;
void init() {
tot = last = ;
sn[tot++].init();
}
int newnode() {
sn[tot].init();
return tot++;
}
void extend(int c) {
int np = newnode(),p = last;
sn[np].len = sn[last].len + ;
while(p != - && sn[p].son[c] == -) {
sn[p].son[c] = np;
p = sn[p].f;
}
if(p == -) sn[np].f = ;
else {
int q = sn[p].son[c];
if(sn[p].len + == sn[q].len) sn[np].f = q;
else {
int nq = newnode();
sn[nq] = sn[q];
sn[nq].len = sn[p].len + ;
sn[np].f = sn[q].f = nq;
while(p != - && sn[p].son[c] == q) {
sn[p].son[c] = nq;
p = sn[p].f;
}
}
}
last = np;
}
} sam;
char str[maxn];
int fail[maxn];
void getFail(const char *word) {
fail[] = -;
fail[] = ;
for(int i = ,j = -; word[i]; ++i) {
while(j != - && word[i] != word[j]) j = fail[j];
fail[i+] = ++j;
}
}
char text[maxn];
int mymin(int x,int y) {
return x > y?y:x;
}
int mymax(int x,int y) {
return x > y?x:y;
}
int FindIndex(const char *word,int (*f)(int,int),int idx,int len) {
for(int i = , j = ; text[i] ; ++i) {
while(j > - && word[j] != text[i]) j = fail[j];
if(!word[++j]) {
if(i - len + <= len)idx = f(idx,i - len + );
j = fail[j];
}
}
return idx;
}
int main() {
int kase,len;
scanf("%d",&kase);
while(kase--) {
sam.init();
scanf("%d",&len);
scanf("%s",str);
int p = ;
for(int i = ; i < (len<<); ++i)
sam.extend(str[i%len]-'a');
string ss = "",sb = "";
for(int i = ; i < len; ++i) {
for(int j = ; j >= ; --j) {
if(sam.sn[p].son[j] != -) {
p = sam.sn[p].son[j];
ss += char('a' + j);
break;
}
}
}
int clockwise = sam.sn[p].len - len + ;
getFail(ss.c_str());
strcpy(text,str);
strcpy(text + len,str);
clockwise = FindIndex(ss.c_str(),mymin,len*,len);
reverse(str,str + len);
sam.init();
for(int i = p = ; i < (len<<); ++i) {
sam.extend(str[i%len]-'a');
}
for(int i = ; i < len; ++i) {
for(int j = ; j >= ; --j) {
if(sam.sn[p].son[j] != -) {
p = sam.sn[p].son[j];
sb += char('a' + j);
break;
}
}
}
getFail(sb.c_str());
strcpy(text,str);
strcpy(text + len,str);
int anticlockwise = len - FindIndex(sb.c_str(),mymax,,len) + ;
if(ss == sb) {
if(clockwise == anticlockwise) {
printf("%d %d\n",clockwise,);
} else if(clockwise < anticlockwise) {
printf("%d %d\n",clockwise,);
} else printf("%d %d\n",anticlockwise,);
} else if(ss < sb) printf("%d %d\n",anticlockwise,);
else printf("%d %d\n",clockwise,);
}
return ;
}

HDU 5442 Favorite Donut的更多相关文章

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

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

  2. hdu 5442 Favorite Donut 后缀数组

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

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

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

  4. HDU 5442——Favorite Donut——————【最大表示法+kmp | 后缀数组】

    Favorite Donut Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

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

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

  6. Favorite Donut(HDU 5442)最小表示法+二分

    题目给出一个字符串,由a~z表示甜度,随字典序增大,字符串首尾相连形成一个圈,要求从一个位置开始字典序最大的字符串,输出位置以及是顺时针还是逆时针表示.顺时针用0表示,逆时针用1表示. 此题只需要查找 ...

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

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

  8. HDU 5442 后缀自动机(从环字符串选定一个位置 , 时针或顺时针走一遍,希望得到字典序最大)

    http://acm.hdu.edu.cn/showproblem.php?pid=5442 题目大意: 给定一个字符串,可理解成环,然后选定一位置,逆时针或顺时针走一遍,希望得到字典序最大,如果同样 ...

  9. hdu 5442 (ACM-ICPC2015长春网络赛F题)

    题意:给出一个字符串,长度是2*10^4.将它首尾相接形成环,并在环上找一个起始点顺时针或逆时针走一圈,求字典序最大的走法,如果有多个答案则找起始点最小的,若起始点也相同则选择顺时针. 分析:后缀数组 ...

随机推荐

  1. POJ 1635 Subway tree systems 有根树的同构

    POJ 1635 题目很简单 给个3000节点以内的根确定的树 判断是否同构.用Hash解决,类似图的同构,不过效率更高. #include<iostream> #include<c ...

  2. JavaGraphics类的绘图方法

    Graphics类提供基本绘图方法,Graphics类提供基本的几何图形绘制方法,主要有:画线段.画矩形.画圆.画带颜色的图形.画椭圆.画圆弧.画多边形.画字符串等. 1. 画线段:在窗口中画一条线段 ...

  3. Android 数据库

    官方文档:https://developer.android.com/training/basics/data-storage/databases.html#WriteDbRow 原帖:http:// ...

  4. bzoj1036 树的统计(树链剖分+线段树)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 15120  Solved: 6141[Submit ...

  5. [Swift通天遁地]二、表格表单-(10)快速添加日期选择/多选/动作表单/地图等自定义表单

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  6. redis+php实现秒杀

    使用redis队列,因为pop操作是原子的,即使有很多用户同时到达,也是依次执行,推荐使用(mysql事务在高并发下性能下降很厉害,文件锁的方式也是) 先将商品库存如队列 1 2 3 4 5 6 7 ...

  7. BZOJ 1129 exgcd+CRT+线段树

    思路: 先copy一下百度百科 作为预备知识吧多重全排列定义:求r1个1,r2个2,…,rt个t的排列数,设r1+r2+…+rt=n,设此排列数称为多重全排列,表示为$P(n;r1,r2,…,rt)$ ...

  8. Linq学习(二)-本次学习用到的资料

    本次学习用到的数据库初始化脚本如下 use KMS create table Blog_User ( UserId ,1), NickName ), CreateTime datetime ) cre ...

  9. Angular——内置指令

    内置指令 ng-app 指定应用根元素,至少有一个元素指定了此属性. ng-controller 指定控制器 ng-show控制元素是否显示,true显示.false不显示 ng-hide控制元素是否 ...

  10. (一)Python 学习第一天--基础知识,列表

    1. .pyc文件 .pyc文件:在python3中,当模块运行时会自动生成在_pycache_文件夹中,其中c为compiled的缩写. Python是一门现编译后解释的语言,在运行时首先寻找.py ...