题目链接

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

如果两个一样, 输出位置靠前的一个, 如果位置也一样, 输出顺时针的那个。

显然是一个最大表示法。 麻烦的是逆时针的情况, 因为要输出位置靠前的一个。 但是逆时针求出来的是字符串反转之后靠前的, 所以应该求一遍kmp, 找出来最靠后的一个位置。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <string>
  5. using namespace std;
  6. const int maxn = 4e4+;
  7. int a[maxn], b[maxn], pos[maxn], nxt[maxn], c[maxn];
  8. int getMax(int a[], int n)
  9. {
  10. int i, j, k;
  11. for(i = , j = ; i<n&&j<n; ) {
  12. for(k = ; k<n&&a[i+k]==a[j+k]; k++)
  13. ;
  14. if(k>=n)
  15. break;
  16. if(a[i+k]>a[j+k])
  17. j += k+;
  18. else
  19. i += k+;
  20. if(i == j)
  21. j++;
  22. }
  23. return i;
  24. }
  25. int solve(string s, int a[], int n)
  26. {
  27. for(int i = ; i < n; i++) {
  28. a[i] = s[i]-'a';
  29. }
  30. for(int i = n; i < *n-; i++) {
  31. a[i] = a[i-n];
  32. }
  33. int pos = getMax(a, n);
  34. return pos;
  35. }
  36. void init_kmp(int m) {
  37. int i = , j = -;
  38. nxt[] = -;
  39. while(i<m) {
  40. if(j == - || c[i] == c[j]) {
  41. ++i, ++j;
  42. nxt[i] = j;
  43. } else {
  44. j = nxt[j];
  45. }
  46. }
  47. }
  48. int kmp(int n)
  49. {
  50. int cnt = ;
  51. int i = , j = ;
  52. while(i<*n-) {
  53. if(j == - || b[i] == c[j]) {
  54. i++, j++;
  55. } else {
  56. j = nxt[j];
  57. }
  58. if(j == n) {
  59. pos[cnt++] = i;
  60. j = nxt[j];
  61. }
  62. }
  63. return cnt;
  64. }
  65. int main()
  66. {
  67. int t, n;
  68. string s;
  69. cin>>t;
  70. while(t--) {
  71. cin>>n>>s;
  72. int pos1 = solve(s, a, n);
  73. int num = , flag = -;
  74. reverse(s.begin(), s.end());
  75. int pos2 = solve(s, b, n);
  76. int tmp1 = pos1, tmp2 = pos2;
  77. while(num < n) {
  78. if(a[pos1] > b[pos2]) {
  79. flag = ;
  80. break;
  81. } else if(a[pos1] < b[pos2]) {
  82. flag = ;
  83. break;
  84. } else {
  85. pos1++;
  86. pos2++;
  87. num++;
  88. }
  89. }
  90. int cnt = ;
  91. for(int i = tmp2; i < tmp2+n; i++) {
  92. c[cnt++] = b[i];
  93. }
  94. init_kmp(n);
  95. cnt = kmp(n);
  96. tmp2 = pos[cnt-]%n;
  97. if(num == n) {
  98. if(tmp1+ <= n-tmp2) {
  99. flag = ;
  100. } else {
  101. flag = ;
  102. }
  103. }
  104. if(flag) {
  105. printf("%d %d\n", tmp1+, !flag);
  106. } else {
  107. printf("%d %d\n", n-tmp2, !flag);
  108. }
  109. }
  110. return ;
  111. }

hdu 5442 Favorite Donut 最大表示法+kmp的更多相关文章

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

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

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

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

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

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

  4. hdu 5442 Favorite Donut 后缀数组

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

  5. HDU 5442 Favorite Donut

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

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

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

  7. HDU 1711 Number Sequence (字符串匹配,KMP算法)

    HDU 1711 Number Sequence (字符串匹配,KMP算法) Description Given two sequences of numbers : a1, a2, ...... , ...

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

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

  9. HDU 3374 最小/大表示法+KMP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题意:给定一个串s,该串有strlen(s)个循环同构串,要求输出字典序最小的同构串的下标,字典 ...

随机推荐

  1. [原创]Windows下Google V8 javascript引擎编译

    项目用到将v8嵌入到C++的情况,公司没时间研究,只有在家研究,编译过程一堆坑.记录一下. 网上百度的都是基于vs2010,或者早版本的v8编译,最新版本应该使用vs2013\vs2015.本文介绍的 ...

  2. [转载]vs2010中臃肿的ipch和sdf文件

    使用VS2010建立C++解决方案时,会生成SolutionName.sdf和一个叫做ipch的文件夹,这两个文件再加上*.pch等文件使得工程变得非常的庞大,一个简单的程序都会占用几十M的硬盘容量, ...

  3. mac git 命令提示

    直接进入正题: $ brew list 查看你是否已经安装了"bash-completion",如果没有,继续往下看: $ brew install bash-completion ...

  4. bzoj 1912 : [Apio2010]patrol 巡逻 树的直径

    题目链接 如果k==1, 显然就是直径. k==2的时候, 把直径的边权变为-1, 然后在求一次直径. 变为-1是因为如果在走一次这条边, 答案会增加1. 学到了新的求直径的方法... #includ ...

  5. MySQL query_cache_type 详解

    MySQL设置查询缓存的用意: 把查询到的结果缓存起来,下次再执行相同查询时就可以直接从结果集中取:这样就比重新查一遍要快的多. 查询缓存的最终结果是事与愿违: 之所以查询缓存并没有能起到提升性能的做 ...

  6. Linux文件解压缩详解

    tar命令 我们知道在Windows下最常见的压缩文件就只有两种,一是,zip,另一个是.rar.可是Linux就不同了,它有.gz..tar.gz.tgz.bz2..Z..tar等众多的压缩文件名, ...

  7. Linux命令(持续更新ing)

    *.命令语法:  a.在进行参数设定时,通常为“-”号,若为完整参数名称,则输入“--”符号;  b.指令太长的时候,可以使用“\”符号使指令连续到下一行;  c.各种符号的意义:    ''     ...

  8. Nutch配置

    http://www.linuxidc.com/Linux/2011-12/48782.htm http://wiki.apache.org/nutch/NutchHadoopTutorial htt ...

  9. Qt 鼠标样式特效探索样例(一)——利用时间器调用QWidget.move()函数

    Qt 鼠标样式特效探索样例(一)       心血来潮,突然想在Qt里玩一把鼠标样式,想到在浏览网页时,经常看到漂亮的鼠标动画,于是今天摸索着乱写个粗糙的demo,来满足自己的好奇心. 效果图 方案要 ...

  10. cf459C Pashmak and Buses

    C. Pashmak and Buses time limit per test 1 second memory limit per test 256 megabytes input standard ...