Favorite Donut

Favorite Donut

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

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

2015 ACM/ICPC Asia Regional Changchun Online

题意:Lulu喜欢吃炸面圈,炸面圈有n个部分组成,每个部分由小写字母代表其甜度,Lulu总是从最甜的开始吃,两个方向,哪个最甜吃哪个。输出满足她要求吃法的最开始的下标,和方向。最大最小表示法

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<algorithm>
  6
  7 using namespace std;
  8
  9 #define maxn 40008
 10
 11 int n, Next[maxn];
 12
 13 void Getnext(char s[], int n)   // kmp获得Next数组,next会出现编译错误,我也不造为什么……
 14 {
 15     int j, k;
 16     j = 0;
 17     k = Next[0] = -1;
 18     while(j < n)
 19     {
 20         if(k == -1 || s[j] == s[k])
 21
 22          Next[++j] = ++k;
 23         else
 24             k = Next[k];
 25     }
 26 }
 27
 28 int GETNEXT(char s[], int n)  // 找下标最小的开始的串满足吃法
 29 {
 30     int i, j;
 31     i = 0;
 32     j = 1;
 33     while(i < n && j < n)   // i, j比较,每次让相对字典序小的改变,最后肯定有一个超过n,那个没超过n的就是满足题意的
 34     {
 35         int k = 0;
 36         while( s[i+k] == s[j+k] && k < n)  // 如果这两个下标对应的字典序相等,继续向下比较,知道不等为止
 37             k++;
 38         if(k == n)
 39             break;
 40         if(s[i+k] > s[j+k])
 41         {
 42             if(j+k > i)
 43                 j = j + k + 1;
 44             else
 45                 j = i + 1;
 46         }
 47         else
 48         {
 49             if(i+k > j)
 50                 i = i + k + 1;
 51             else
 52                 i = j + 1;
 53         }
 54     }
 55     return min(i, j);
 56 }
 57
 58 int KMP(char s[], char s1[], int n, int m)   //在逆串中找开始下标最后边的满足题意的串(就是下标最小的,next, kmp优化
 59 {
 60     int i, j, ans;
 61     i = j = 0;
 62     while(j < m)
 63     {
 64         while( i == -1 || (s[i] == s1[j] && j < m))
 65             i++, j++;
 66
 67         if(i == n)
 68             ans = j - n;
 69         i = Next[i];
 70     }
 71     return ans;
 72 }
 73
 74 int main()
 75 {
 76     int c;
 77     scanf("%d", &c);
 78     char s[maxn], s1[maxn], s2[maxn], s3[maxn], s4[maxn];
 79
 80     while(c--)
 81     {
 82         memset(s, 0, sizeof(s));
 83         memset(s1, 0, sizeof(s1));
 84         memset(s2, 0, sizeof(s2));
 85         memset(s3, 0, sizeof(s3));
 86         memset(s4, 0, sizeof(s4));
 87
 88         scanf("%d", &n);
 89         scanf("%s", s);
 90         strcpy(s1, s);
 91         strcat(s1, s);
 92
 93         int a = GETNEXT(s1, n);  // 找到正序的满足题意的下标
 94         strncpy(s3, s1+a, n);   // 把满足题意的s3中
 95
 96         strrev(s);
 97         strcpy(s2, s);
 98         strcat(s2, s);
 99         int b = GETNEXT(s2, n);  // 找逆串中的满足题意的下标
100         strncpy(s4, s2+b, n);
101
102         Getnext(s4, n);
103         b = KMP(s4, s2, n, 2*n-1);   // 找逆串中满足题意的最后边的下标,也就是正串中最前边的下标……
104         strncpy(s4, s2+b, n);
105
106         int g = strcmp(s3, s4);
107
108         if(g == 0)
109         {
110             if(a+1 <= n-b)
111                 printf("%d 0\n", a+1);
112             else
113                 printf("%d 1\n", n-b);
114         }
115         else if(g > 0)
116             printf("%d 0\n", a+1);
117         else
118             printf("%d 1\n", n-b);
119     }
120     return 0;
121 }
122 /*
123 4
124
125 4
126 aaab
127 4
128 abca
129 6
130 abcabc
131 4
132 abab
133 */
时间: 2024-10-06 04:23:48

Favorite Donut的相关文章

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

题目链接: Hdu 5442 Favorite Donut 题目描述: 给出一个文本串,找出顺时针或者逆时针循环旋转后,字典序最大的那个字符串,字典序最大的字符串如果有多个,就输出下标最小的那个,如果顺时针和逆时针的起始下标相同,则输出顺时针. 解题思路: 看到题目感觉后缀数组可以搞,正准备犯傻被队友拦下了,听队友解释一番,果断丢锅给队友.赛后试了一下后缀数组果然麻烦的不要不要的(QWQ),还是最大最小表示法 + KMP来的干净利索. 最大表示法:对于一个长度为len文本串,经过循环旋转得到长度

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 Problem Description Lulu has a sweet tooth. Her favorite food is ring donut. Everyday she buy

hdu 5442 Favorite Donut 后缀数组

Favorite Donut Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5442 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 consis

使用Donut Caching和Donut Hole Caching在ASP.NET MVC应用中缓存页面

Donut Caching是缓存除了部分内容以外的整个页面的最好的方式,在它出现之前,我们使用"输出缓存"来缓存整个页面. 何时使用Donut Caching 假设你有一个应用程序中有像"主页"这种页面,它除了用户登录的用户名以外总是给用户呈现相同的或者很少变化的内容.这时你可能需要缓存大部分的内容.加入你使用"输出缓存"并应用一个VaryByParam UserID来做缓存处理,那么整个页面会为每个访问用户生成缓存,但是这当我们有很大量的登陆用

使用 angular directive 和 json 数据的 D3 带标签 donut chart示例

利用angular resource加载priorityData.json中的json数据,结合D3画出甜甜圈图.运行index.html结果如图所示: priorityData.json中json数据如下: { "priority":{ "Blocker":12, "Critical":18, "Major":5, "Minor":30, "Trivial":24 } } index.

msf+Donut执行程序

地址:donut:https://github.com/TheWover/donut 介绍:是一个shellcode生成工具,可以将.NET程序集等转换为shellcode. 使用:donut.exe -f (指定文件名) -a 2 (系统位数2代表64位) -o (输出文件名) msf设置参数: ps:msf若没有此博客自行添加到对应目录:https://github.com/rapid7/metasploit-framework/blob/master/modules/post/window

Donut和MSF以shellcode注入的方式执行任意文件

准备工具 MSF https://github.com/rapid7/metasploit-framework/wiki/Nightly-Installers Donut https://github.com/TheWover/donut 准备的shellcode_inject.rb代码 ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.co

hdu 5442 Favorite Donut 最大表示法+KMP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5442 题意: 有一个由小写字母组成的字符串(长度为n),首尾相接,求顺时针转和逆时针转的情况下,长度为n的最大字典序的字符串的首位的位置. 如果顺时针和逆时针求得的字符串相同,则选择开始位置较前的,如果开始位置也相同,则选择顺时针的. 如abcd,那么顺时针可以是abcd,bcda,cdab,dabc.逆时针可以是adcb,dcba,cbad,badc. 思路: 顺时针的情况下,直接求最大字典序的位

hdu5442 Favorite Donut

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5442 题目大意:给你一个长度为n的字符串,将它首尾相连成环.问你这个环上找一个长度为n的字典序最大的串(你可以沿顺时针或逆时针找),如果有多个这样的串,输出首字母标号最小的,如果还有多个,输出顺时针的 解: 1.最小表示法解(时间复杂度:O(n)) 最小表示法~ 2.后缀数组(时间复杂度:O(logn)) 比赛的时候想到的方法,然而并没有写出来,不好写+高时间复杂度=不推荐 最小表示法: 1 /*