zoukankan      html  css  js  c++  java
  • 字符串周期的问题

    如果s1s2s3s4...sn = s3s4s5...sns1s2

    那么说明s1=s2,s2=s3,s3=s4,s4=s5....

    说明这个字符串是一个周期串。

    更一般的情况是 s(i)s(i+1)...s(n)s(1)...s(i-1) = s(j)s(j+1)..s(n)s(1)...s(j-1)  i!=j

    那么说明以i开始的字符串是一个周期串。

    题目:给我们一个字符串,要我们求它的最小表示,输出从哪个位置开始, 如果有多个, 那么返回最大的位置。

    首先,用最小表示法求得开始位置最小的,然后用kmp求得循环节,然后强行移到最后。

    当然了,也可以求出字典序最小的出现了多少次。

    比如hdu3374

    要求字典序最小和字典序最大的表示出现了多少次。

      1 #pragma warning(disable:4996)
      2 #include <iostream>
      3 #include <stdio.h>
      4 #include <string.h>
      5 #include <math.h>
      6 #include <string>
      7 #include <vector>
      8 #include <queue>
      9 #include <set>
     10 #include <map>
     11 #include <algorithm>
     12 #include <functional>
     13 using namespace std;
     14 
     15 const int N = 1000000 + 10;
     16 char str[N];
     17 char tmp[N];
     18 int next[N];
     19 void getNext(char *str,int n)
     20 {
     21     int i = 0,j = -1;
     22     next[0] = -1;
     23     while(i<n)
     24     {
     25         if(j==-1||str[i]==str[j])
     26         {
     27             ++i;
     28             ++j;
     29             next[i] = j;
     30         }
     31         else
     32             j = next[j];
     33     }
     34 }
     35 
     36 int minimalRepresentation(char *str, int n)
     37 {
     38     int i = 0,j = 1, k = 0;
     39     while(i<n && j<n && k<n)
     40     {
     41         int t = str[(i+k)%n] - str[(j+k)%n] ;
     42         if(t == 0)
     43             k++;
     44         else
     45         {
     46             if(t>0)
     47                 i+=k+1;
     48             else 
     49                 j+=k+1;
     50             if(i==j)
     51                 j++;
     52             k = 0;
     53         }
     54     }
     55     return i < j ? i : j;
     56 }
     57 int maxRepresentation(char *str, int n)
     58 {
     59     int i = 0,j = 1, k = 0;
     60     while(i<n && j<n && k<n)
     61     {
     62         int t = str[(i+k)%n] - str[(j+k)%n] ;
     63         if(t == 0)
     64             k++;
     65         else
     66         {
     67             if(t>0)
     68                  j+=k+1;
     69             else 
     70                 i+=k+1;
     71                
     72             if(i==j)
     73                 j++;
     74             k = 0;
     75         }
     76     }
     77     return i < j ? i : j;
     78 }
     79 int solve(char *str, int n)
     80 {
     81     getNext(str,n);
     82     return n/(n-next[n]);//n-next[n] 是周期
     83 }
     84 int main()
     85 {
     86     int idx1,times1,idx2,times2,n;
     87     while(scanf("%s",str)!=EOF)
     88     {
     89         n = strlen(str);
     90         idx1 = minimalRepresentation(str,n);
     91         for(int i=0;i<n;++i)
     92             tmp[i] = str[(i+idx1)%n];
     93         times1 = solve(tmp,n);
     94         idx2 = maxRepresentation(str,n);
     95         for(int i=0;i<n;++i)
     96             tmp[i] = str[(i+idx2)%n];
     97         times2 = solve(tmp,n);
     98         printf("%d %d %d %d
    ",idx1+1,times1,idx2+1,times2);
     99         
    100     }
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    dom4j修改,获取,增加xml中某个元素的属性值
    SVN功能详解
    采用RPC方式和document方式 开发Axis2的WebService客户端
    记录我电脑的环境变量配置
    Java float保留两位小数或多位小数
    c#中获取服务器IP,客户端IP以及Request.ServerVariables详细说明
    说说Java观察者模式
    2018第12周总结
    聊聊Java反射
    Java注解总结2
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4806246.html
Copyright © 2011-2022 走看看