题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5442

打比赛的时候还没学kmp更没有学最大最小表示法,之后做完了kmp的专题,学了它们,现在再来做这道题,断断续续做了一段时间最终还是对了;

题意:就是有一个甜圈由n个部分组成,每部分的甜度由一个小写字母来表示(z是最甜的,a是最不甜的),Lulu吃它的时候必须从一个部分开始,然后必须吃这部分相邻的部分,一直到把n部分吃完为止;所以她只有两种吃法:正序或逆序;但是她总是喜欢吃最甜的你,总是选择字典序最大的来吃当有多种字典序相等的时候选择开始下标最小的,当下标也相等的时候则选择正序;

思路:求最大字典序我们可以用最大表示法来求,我们用s0来存两次串的正序,s1来存两次串的逆序,然后分别求出s0,s1中的最大字典序序列并分别存入a b中,但是b是逆序的,所以我们必须要求出来b串在s1中最先先出现的位置(最后面的位置);所以可以用kmp进行匹配;

看代码吧

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
#define N 40200 char s[N], s0[N], s1[N], a[N], b[N];
int Next[N]; int MAX_INDEX(char s[], int n)///最大表示法求最大字典序的起始下标;
{
int i = , j = , k = ;
while(i<n && j<n && k<n)
{
int t = s[(i+k)%n] - s[(j+k)%n];
if(t==)
k++;
else
{
if(t<)
i = i+k+;
else
j = j+k+;
if(i==j)
j++;
k = ;
}
}
return min(i, j);
} void GetNext(char s[], int n)///求子串的Next数组;
{
int i=, j=-;
Next[] = -;
while(i<n)
{
if(j==- || s[i]==s[j])
Next[++i] = ++j;
else
j = Next[j];
}
} int kmp(char sub[], int n, char Mum[], int m)///长度为n的子串在长度为m的母串中的位置,并返回开始匹配的下标,若没有返回-1;
{
int i=, j=;
while(i<m)
{
if(j==- || Mum[i]==sub[j])
i++,j++;
else
j = Next[j];
if(j==n)
return i-n+;
}
return -;
} int main()
{
int T, dir,ans;
scanf("%d", &T);
while(T--)
{
memset(a, , sizeof(a));
memset(b, , sizeof(b));
memset(s0, , sizeof(s0));
memset(s1, , sizeof(s1)); int len;
scanf("%d%s", &len, s); strcpy(s0, s);
strcat(s0, s);///正着存两次放进s0;
s0[*len] = '\0'; int j=;
for(int i=*len-; i>=; i--)
s1[j++] = s0[i];
s1[j] = '\0';///倒着存两次放进s1; int Max_index1 = MAX_INDEX(s0, *len);
int Max_index2 = MAX_INDEX(s1, *len);///用最大表示法求出最大字典序的下标; strncpy(a, s0+Max_index1, len);
strncpy(b, s1+Max_index2, len);
a[len] = '\0'; b[len] = '\0';///分别用字符串a,b来保存正序和逆序的最大字典序的字符; GetNext(b, len); int m = kmp(b, len, s1+Max_index2+, *len-Max_index2-);
while(m!=- && m+Max_index2!=len)///下标不能是len;
{
Max_index2 += m;
m = kmp(b, len, s1+Max_index2+, *len-Max_index2-);
}///因为s1串是逆序的用最大表示法得到的下标在逆序中是最靠前的,然而在正序中确实最靠后的,所以要用kmp求出s1串中与b一样的串最后的位置所在; if(strcmp(a, b)>)
dir = , ans = Max_index1 + ;
else if(strcmp(a, b)<)
dir = , ans = len - Max_index2;
else///当串一样时, 要考虑谁考前,结果就是谁;
{
if(Max_index1 + <= len - Max_index2)
dir = , ans = Max_index1 + ;
else
dir = , ans = len - Max_index2;
}
printf("%d %d\n", ans, dir);
}
return ;
}

Favorite Donut--hdu5442(2015年长春网选赛,kmp,最大表示法)的更多相关文章

  1. hdu5442 Favorite Donut 后缀数组 长春网赛

    wa从一点到晚上11点没停过,也不知道为什么错,第二天换了个思路做,终于过了.这题还是有点问题的,数据有点水,我看到有人贴的代码baabbaab这组数据是4 0,明显错的,但是却可以过. 下面的是我第 ...

  2. hdu5442(2015长春赛区网络赛1006)后缀数组+KMP /最小表示法?

    题意:给定一个由小写字母组成的长度为 n 的字符串,首尾相连,可以从任意一个字符开始,顺时针或逆时针取这个串(长度为 n),求一个字典序最大的字符串的开始字符位置和顺时针或逆时针.如果有多个字典序最大 ...

  3. hdu 5441 Travel (2015长春网赛)

    http://acm.hdu.edu.cn/showproblem.php?pid=5441 题目大意是给一个n个城市(点)m条路线(边)的双向的路线图,每条路线有时间值(带权图),然后q个询问,每个 ...

  4. hdu 5443 (2015长春网赛G题 求区间最值)

    求区间最值,数据范围也很小,因为只会线段树,所以套了线段树模板=.= Sample Input3110011 151 2 3 4 551 21 32 43 43 531 999999 141 11 2 ...

  5. hihocoder1236(2015长春网赛J题) Scores(bitset && 分块)

    题意:给你50000个五维点(a1,a2,a3,a4,a5),50000个询问(q1,q2,q3,q4,q5),问已知点里有多少个点(x1,x2,x3,x4,x5)满足(xi<=qi,i=1,2 ...

  6. ACM学习历程—HDU 5443 The Water Problem(RMQ)(2015长春网赛1007题)

    Problem Description In Land waterless, water is a very limited resource. People always fight for the ...

  7. ACM学习历程—HDU 5446 Unknown Treasure(数论)(2015长春网赛1010题)

    Problem Description On the way to the next secret treasure hiding place, the mathematician discovere ...

  8. hdu 4764 && 2013长春网赛题解

    一个组合游戏题. 解答: 从后面往前面推,首先n-1是必胜位,然后前面的k位是必败位,如此循环下去.所以题目就容易了! 代码: #include<cstdio> using namespa ...

  9. 2013长春网赛1009 hdu 4767 Bell(矩阵快速幂+中国剩余定理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4767 题意:求集合{1, 2, 3, ..., n}有多少种划分情况bell[n],最后结果bell[ ...

随机推荐

  1. location.href 不响应的解决方法

    在某些时候修改元素的值的时候过快会导致失效 1.window.open("","_blank") 代替  不过也是打开新窗口 2.延迟调用location.hr ...

  2. Unix系统编程()复制文件描述符

    Bourne shell的IO重定向语法2>&1,意在通知shell把标准错误(文件描述符2)重定向到标准输出(文件描述符1).因此下列命令将把标准输出和标准错误写入result.log ...

  3. Android——excise(用线性布局、表格布局、相对布局做发送邮件界面)

    LinearLayout <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns ...

  4. hive中array嵌套map以及行转列的使用

    1. 数据源信息 {"student": {"name":"king","age":11,"sex" ...

  5. 70个shell经常使用操作

    1) 怎样向脚本传递參数 ? ./script argument 样例: 显示文件名脚本 ./show.sh file1.txt cat show.sh #!/bin/bash echo $1 2) ...

  6. elasticsearch安装与使用(1)-- centos7 elasticsearch的两种简单安装方法

    转自:http://www.cnblogs.com/miao-zp/p/6003160.html 简单修改 前言 elasticsearch(下面称为ES)是一个基于Lucene的搜索服务器(By 百 ...

  7. python的post请求抓取数据

    python通过get方式,post方式发送http请求和接收http响应-urllib urllib2 python通过get方式,post方式发送http请求和接收http响应-- import  ...

  8. uva624 CD (01背包+路径的输出)

    CD Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Status Practice UVA 624 ...

  9. jdk 配置时时区设置

    在eclipse中的 Default VM Arguments:添加 -Duser.timezone=Aisa/Shanghai

  10. unity发射弓箭轨迹的实现

    无论是愤怒的小鸟,还是弓箭发射功能,亦或者模拟炮弹受重力影响等抛物线轨迹,都可以使用本文的方法,模拟绝对真实. 和往常一样,先说原理.就是抛物运动,在垂直方向上做加速度运动,在水平方向上,做匀速运动. ...