Favorite Donut--hdu5442(2015年长春网选赛,kmp,最大表示法)
题目链接: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,最大表示法)的更多相关文章
- hdu5442 Favorite Donut 后缀数组 长春网赛
wa从一点到晚上11点没停过,也不知道为什么错,第二天换了个思路做,终于过了.这题还是有点问题的,数据有点水,我看到有人贴的代码baabbaab这组数据是4 0,明显错的,但是却可以过. 下面的是我第 ...
- hdu5442(2015长春赛区网络赛1006)后缀数组+KMP /最小表示法?
题意:给定一个由小写字母组成的长度为 n 的字符串,首尾相连,可以从任意一个字符开始,顺时针或逆时针取这个串(长度为 n),求一个字典序最大的字符串的开始字符位置和顺时针或逆时针.如果有多个字典序最大 ...
- hdu 5441 Travel (2015长春网赛)
http://acm.hdu.edu.cn/showproblem.php?pid=5441 题目大意是给一个n个城市(点)m条路线(边)的双向的路线图,每条路线有时间值(带权图),然后q个询问,每个 ...
- hdu 5443 (2015长春网赛G题 求区间最值)
求区间最值,数据范围也很小,因为只会线段树,所以套了线段树模板=.= Sample Input3110011 151 2 3 4 551 21 32 43 43 531 999999 141 11 2 ...
- 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 ...
- 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 ...
- ACM学习历程—HDU 5446 Unknown Treasure(数论)(2015长春网赛1010题)
Problem Description On the way to the next secret treasure hiding place, the mathematician discovere ...
- hdu 4764 && 2013长春网赛题解
一个组合游戏题. 解答: 从后面往前面推,首先n-1是必胜位,然后前面的k位是必败位,如此循环下去.所以题目就容易了! 代码: #include<cstdio> using namespa ...
- 2013长春网赛1009 hdu 4767 Bell(矩阵快速幂+中国剩余定理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4767 题意:求集合{1, 2, 3, ..., n}有多少种划分情况bell[n],最后结果bell[ ...
随机推荐
- Linux kernel 之 uart 驱动解析
uart 是一种非常之常见的总线,比如DEBUG信息输出,小数据量数据传输,485,以及蓝牙的控制,GPS,很多都是通过uart 进行数据传输并进行控制. 在Linux kernel 内部,uart ...
- JavaScript 框架 jQuery 的下载和安装
jQuery 简介: jQuery 是一个 JavaScript 库. jQuery 极大地简化了 JavaScript 编程. jQuery 很容易学习. jQuery 下载: // 官网: htt ...
- at91 uart driver for vxworks
/* at91UART.c - AT91RM9200 serial driver */ /* Copyright 2003-2004 Coordinate Co., Ltd. */ /* Copyri ...
- VIM打开shell脚本中文乱码解决
1. 查找 .vimrc文件 通常有2个地方保存这个文件的: (1) 在/etc/文件夹下面,是所有用户的vim配置 (2)每个用户的开始登录的文件夹下面,有些不一定有,比如hadoop用户,则在/h ...
- asp.net 正在加载效果实现
最近研究了下asp.net 正在加载的实现原理,总结了以下实现方法 首先,我们有个div显示内容为正在加载.. 当然也可以考虑用图片或者其他的,不过考虑到速度,建议直接文字提示就行,然后设置div ...
- js获取字符串的实际长度并截断实际长度
在项目中有这样一个需求,就是一个很长的字符串,需要截断成几组字符串,而这几组字符串里既包含汉字,又包含字母,下面提供了几种方法 1,获取字符串的长度 function getstrlength(str ...
- android jni log
在编写的jni时,经常需要输出打印信息进行调试,而C中printf在jni中没有效果,这时就需要使用NDK提供的函数. 1. jni中包含头文件 #include <android/log.h& ...
- bootstrap基础学习二篇
这篇学习网格系统(Grid System) Bootstrap 提供了一套响应式.移动设备优先的流式网格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列. 1.网格选项: ...
- hdu 4928 Series 2 (优化+模拟)
题意: 一个含n个数的序列a,每两个相邻的数相减得到一个新数,这些数组成一个新的序列. 假设全部得到的序列都满足非严格的单调性.则原序列为nice series.假设给出的序列 本来不满足单调性.它是 ...
- MyBitis(iBitis)系列随笔之二:类型别名(typeAliases)与表-对象映射(ORM)
类型别名(typeAliases): 作用:通过一个简单的别名来表示一个冗长的类型,这样可以降低复杂度. 类型别名标签typeAliases中可以包含多个typeAlias,如下 < ...