Revolving Digits

港控/mmm° 2021-10-23 11:56 357阅读 0赞

算法:

扩展KMP + KMP找循环节

ContractedBlock.gif ExpandedBlockStart.gif

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<iostream>
  5. #include<vector>
  6. #include<string>
  7. #include<math.h>
  8. #include<map>
  9. #include<set>
  10. #include<algorithm>
  11. #define MAXN 300010
  12. using namespace std;
  13. char S[MAXN], T[MAXN];
  14. int next[MAXN];
  15. int extend[MAXN];
  16. int knext[MAXN];
  17. int L, E, G, len;
  18. void get_next( )
  19. {
  20. int i = 0, j = 1, k = 1;
  21. len = strlen(T);
  22. next[0] = len;
  23. while( T[i] == T[i + k] )
  24. i++;
  25. next[1] = i;
  26. for( int i = 2; i < len; i++)
  27. {
  28. if( i + next[i - k] < k + next[k] )
  29. next[i] = next[i - k];
  30. else
  31. {
  32. j = max(0, k + next[k] - i);
  33. while( T[j] == T[i + j] )
  34. j++;
  35. next[k = i] = j;
  36. }
  37. }
  38. }
  39. //用KMP判断是否有循环节
  40. void KMP( )
  41. {
  42. int i = 0, j = -1;
  43. knext[0] = -1;
  44. while( i <= len )
  45. {
  46. if( j == -1 || T[i] == T[j] )
  47. {
  48. ++i, ++j;
  49. knext[i] = j;
  50. }
  51. else
  52. j = knext[j];
  53. }
  54. // printf("len = %d knext[len] = %d\n",len,knext[len]);
  55. if( len - knext[len] != 0 && len - knext[len] != len && len % (len - knext[len]) == 0 )
  56. {
  57. len = len - 1 - knext[len] + 1; //循环节长度
  58. }
  59. }
  60. void solve( )
  61. {
  62. int lenx = strlen(T);
  63. for( int i = 0; i < len; i++)
  64. {
  65. if( next[i] >= lenx )
  66. E++;
  67. else if( S[next[i] + i] > S[next[i]] )
  68. {
  69. G++;
  70. }
  71. else
  72. L++;
  73. }
  74. }
  75. int main( )
  76. {
  77. int N, abc = 1;
  78. scanf("%d",&N);
  79. while( N-- )
  80. {
  81. scanf("%s",T);
  82. strcpy(S,T);
  83. strcat(S,T);
  84. memset(next,0,sizeof(next));
  85. memset(knext,0,sizeof(knext));
  86. get_next( );
  87. L = E = G = 0;
  88. KMP( );
  89. solve( );
  90. printf("Case %d: %d %d %d\n",abc++,L,E,G);
  91. }
  92. return 0;
  93. }

转载于:https://www.cnblogs.com/tangcong/archive/2012/08/08/2627835.html

发表评论

表情:
评论列表 (有 0 条评论,357人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Digits

    \\(Digits\\) ![m6C1AO.png][] 这道题目比较简单,首先先打出来暴力,然后一看\\(b\\)的范围,瞬间想到快速幂。 快速幂的精髓是什么?