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

题目大意:给你一个长度为n的字符串,将它首尾相连成环。问你这个环上找一个长度为n的字典序最大的串(你可以沿顺时针或逆时针找),如果有多个这样的串,输出首字母标号最小的,如果还有多个,输出顺时针的

解:

1、最小表示法解(时间复杂度:O(n))

最小表示法~

2、后缀数组(时间复杂度:O(logn))

比赛的时候想到的方法,然而并没有写出来,不好写+高时间复杂度=不推荐

最小表示法:

 /*
* Problem:
* Author: SHJWUDP
* Created Time: 2015/9/16 星期三 16:18:36
* File Name: 1001.cpp
* State:
* Memo:
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm> using namespace std; struct KMP {
int n;
string T; //target string
vector<int> nt;
KMP(const char * _str) {
n=strlen(_str);
T.assign(_str, _str+n);
getFail();
}
void getFail() {
nt.resize(n+);
nt[]=-;
for(int i=, j=-; i<n; ) {
if(j==- || T[i]==T[j]) {
nt[++i]=++j;
} else j=nt[j];
}
}
int match(const char * P) {//pattern string
//在P中找T
int ret=-;
for(int i=, j=; P[i]; ) {
if(j==- || P[i]==T[j]) {
++i;
if(++j==n) {
if(P[i]) ret=i-n;
}
} else j=nt[j];
}
return ret;
}
}; int maximum_representation(const char * s) {
int i, j, k, len=strlen(s);
for(i=, j=, k=; i<len && j<len && k<len; ) {
int tmp=s[(i+k)%len]-s[(j+k)%len];
if(tmp==) ++k;
else {
if(tmp>) j+=k+;//改成小于号是最小表示法
else i+=k+;
if(i==j) ++j;
k=;
}
}
return min(i, j);
} int n;
int main() {
#ifndef ONLINE_JUDGE
freopen("in", "r", stdin);
//freopen("out", "w", stdout);
#endif
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
string str1;
cin>>str1;
int pos1=maximum_representation(str1.c_str());
string str2(str1.rbegin(), str1.rend());
int pos2=maximum_representation(str2.c_str());
str1+=str1;
str2+=str2;
KMP kmp(str2.substr(pos2, n).c_str());
pos2=kmp.match(str2.c_str());
auto cmp=[&]()->bool {
for(int i=; i<n; ++i) {
if(str1[pos1+i]!=str2[pos2+i])
return str1[pos1+i]>str2[pos2+i];
}
return pos1<=n-pos2-;
};
if(cmp()) {
printf("%d 0\n", pos1+);
} else {
printf("%d 1\n", n-pos2);
}
}
return ;
}

后缀数组:

 /*
* Problem:
* Author: SHJWUDP
* Created Time: 2015/9/14 星期一 16:06:34
* File Name: 1001.cpp
* State:
* Memo:
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm> using namespace std; struct SuffixArray {
static const int SIGMA_SIZE=;
int n;//串长+1
vector<int> str;//str中最后一个元素为0
vector<int> sa;//第i大后缀为str[sa[i]:]
vector<int> rank;//str坐标为i的后缀的字典序排名
vector<int> height;//sa[i-1]和sa[i]的最长公共前缀(LCP)
SuffixArray(const char * _str) {
n=strlen(_str)+;
str.resize(n);
for(int i=; i<n; ++i) str[i]=_str[i];
build_sa();
}
void build_sa(int m=SIGMA_SIZE) {
sa.assign(n, );
vector<int> x(n, ), y(n, ), c(m, );//c(字符计数)
//x[i]:str坐标为i的x值rank
//y[i]:y值第i大的str坐标
//*y数组中前k个为y段串不足k长度的串对应str坐标
for(int i=; i<n; ++i) ++c[x[i]=str[i]];
for(int i=; i<m; ++i) c[i]+=c[i-];
for(int i=n-; i>=; --i) sa[--c[x[i]]]=i;
for(int k=; k<=n; k<<=) {
int p=;
//直接利用sa数组排序第二关键字
for(int i=n-k; i<n; ++i) y[p++]=i;
for(int i=; i<n; ++i) if(sa[i]>=k) y[p++]=sa[i]-k;
//基数排序第一关键字
c.assign(m, );
for(int i=; i<n; ++i) ++c[x[y[i]]];
for(int i=; i<m; ++i) c[i]+=c[i-];
for(int i=n-; i>=; --i) sa[--c[x[y[i]]]]=y[i];
//根据sa和y数组计算新的x数组
swap(x, y);
p=; x[sa[]]=;
for(int i=; i<n; ++i) {
x[sa[i]]=y[sa[i-]]==y[sa[i]] && y[sa[i-]+k]==y[sa[i]+k]?p-:p++;
}
if(p >= n)break;
m = p;//下次基数排序的最大值
}
getHeight();
}
void getHeight() {
rank.resize(n);
height.resize(n);
for(int i=; i<n; ++i) rank[sa[i]]=i;
for(int i=, k=; i<n-; ++i) {
//h[i]=height[rank[i]]
if(k) --k; //h[i]>=h[i-1]-1
int j=sa[rank[i]-];
while(str[i+k]==str[j+k]) ++k;
height[rank[i]]=k;
}
}
}; int n;
bool cmp(string a, string b, int x, int y) {
for(int i=; i<n; ++i) {
if(a[x+i]!=b[y+i]) return a[x+i]>b[y+i];
}
return x<=n-y-;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in", "r", stdin);
//freopen("out", "w", stdout);
#endif
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
string str1;
cin>>str1;
string str2(str1.rbegin(), str1.rend());
str1+=str1;
str2+=str2;
SuffixArray sa1(str1.c_str());
int pos1;
for(int i=sa1.n-; i>=; --i) {
if(sa1.sa[i]<n) {
pos1=sa1.sa[i]; break;
}
}
SuffixArray sa2(str2.c_str());
int pos2=-, mi=n;
for(int i=sa2.n-; i>=; --i) {
if(pos2!=-) mi=min(mi, sa2.height[i+]);
if(mi<n) break;
if(sa2.sa[i]<n) pos2=sa2.sa[i];
}
if(cmp(str1, str2, pos1, pos2)) {
printf("%d 0\n", pos1+);
} else {
printf("%d 1\n", n-pos2);
}
}
return ;
}

hdu5442 Favorite Donut的更多相关文章

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

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

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

    Donut Caching是缓存除了部分内容以外的整个页面的最好的方式,在它出现之前,我们使用"输出缓存"来缓存整个页面. 何时使用Donut Caching 假设你有一个应用程序 ...

  3. hdu 5442 Favorite Donut 后缀数组

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

  4. 使用 angular directive 和 json 数据 D3 随着标签 donut chart演示样本

    使用angular resource载入中priorityData.json中间json数据,结合D3绘制甜甜圈图.执行index.html其结果见于图.: priorityData.json中jso ...

  5. ASP.NET MVC 缓存扩展 - Donut Caching

    项目介绍 ASP.NET MVC Extensible Donut Caching brings donut caching to ASP.NET MVC 3 and later. The code ...

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

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

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

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

  8. HDU 5442 Favorite Donut

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

  9. Favorite Donut

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

随机推荐

  1. Centos6.4 aria2 webui-aria2

    wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm rpm -ivh ...

  2. (Tree) 101. Symmetric Tree

    Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For e ...

  3. 【HOW】在InfoPath中如何为浏览和编辑模式设置不同的视图

    1. 在SharePoint Designer中打开要自定义视图的列表.并点击菜单:列表设置 > 在 InfoPath 中设计表单 > {要自定义表单的内容类型},则会自动打开InfoPa ...

  4. SQL Server备份脚本

    declare @bakfile varchar(30), @bakfilediff varchar(30),@pathfull varchar(50),@pathdiff varchar(50)se ...

  5. R语言将字符串矩阵转化为数值型矩阵

    这是原始数据的格式,当运行完下面的命令的时候,结果如下图 x=read.table("C:/Users/Administrator/Desktop/s1.txt") x=as.ma ...

  6. ios 使用Core Image实现高斯模糊

    在iOS和OS X平台上,Core Image都提供了大量的滤镜(Filter),这也是Core Image库中比较核心的东西之一.按照官方文档记载,在OS X上有120多种Filter,而在iOS上 ...

  7. 好的sql

    select count(2) from vw_pmcthtdj A WHERE a.HTBL_ID not in (select jg.jgjs_htid from PMCTJGJS jg wher ...

  8. 【Python】supervisor安装和管理celery

    参考:http://blog.csdn.net/wawa8899/article/details/52743861 参考:http://www.cnblogs.com/mountaingeek/p/5 ...

  9. Tomcat回收连接

    最近公司一个JDK1.4的老项目升级了JDK1.6后BUG不断,最可恶的连接池被占满. 因为是使用tomcat的连接池所以在config下中添加 <Resource name="jdb ...

  10. nodeJs 模块cookie-session api文档中文翻译,偶自己翻译的

    原文英文文档链接点击 说明 简单的 基于cookie的 session中间件 安装 它是一个可以用npm注册的node模块,可以通过npm install命令安装 npm install cookie ...