zoukankan      html  css  js  c++  java
  • HDU-3374 String Problem (最小表示法)

    题意:给你一个字符串,并让他不断的进行循环左移,问字典序最小的字符串是第几个,出现的次数是多少,最大的字符串是第几个,出现的次数是多少?

    分析:最小字符串和最大字符串用最小表示法即可找到,出现的次数,就是循环节循环的次数,用KMP的Nextd的数组得到

    代码如下:

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    const int N = 1000002;
    int Next[N];
    char S[N];
    string T;
    int tlen,loop_len,loop_num;
    string maxxstr;
    string minnstr;
    int maxx_id;
    int minn_id;
    int MINR(string s,int l){        //s是原串(未加倍过),l是原串长
        for(int i=0;i<l;++i)s+=s[i];    //将s串加倍
    
        int i=0,j=1;                    //利用i,j指针移动
        while(i<l&&j<l){
            int k=0;
            while(s[i+k]==s[j+k]&&k<l)++k;    //不断比较直到比较完长度为l的串或两个子串不相等
            if(k==l)return min(i,j);        //若比较出长度为l则直接返回靠前的那个串的开始位置
            if(s[i+k]>s[j+k])i=max(i+k+1,j+1);    //i串比j串大,那么i到i+k中的串都比j串大,i可以直接移动到i+k+1位置,而起始位置比j小的肯定都在j移动过程中比较过,所以i可以直接移动到j+1位置,因此取这两值的最大值
            else j=max(j+k+1,i+1);    //同上
        }
        return min(i,j);            //返回位置靠前的下标
    }
    
    int MAXR(string s,int l){
        for(int i=0;i<l;++i)s+=s[i];
    
        int i=0,j=1;
        while(i<l&&j<l){
            int k=0;
            while(s[i+k]==s[j+k]&&k<l)++k;
            if(k==l)return min(i,j);
            if(s[i+k]<s[j+k])i=max(i+k+1,j+1);
            else j=max(j+k+1,i+1);
        }
        return min(i,j);
    }
    void getNext()
    {
        int j, k;
        j = 0; k = -1; Next[0] = -1;
        while(j < tlen)
            if(k == -1 || T[j] == T[k])
                Next[++j] = ++k;
            else
                k = Next[k];
    
    }
    int main()
    {
    
          while(scanf("%s",S)!=EOF)
          {
            T=S;
          maxxstr="";
          minnstr="";
          tlen=T.size();
          getNext();
          loop_len=tlen-Next[tlen];
          if(tlen%loop_len!=0)
         {
          loop_num=1;
          loop_len=tlen;
         }
          else
          loop_num=tlen/(loop_len);
          minn_id=MINR(T,tlen)+1;
          maxx_id=MAXR(T,tlen)+1;
          cout<<minn_id<<" "<<loop_num<<" "<<maxx_id<<" "<<loop_num<<endl;
          }
        return 0;
    }
  • 相关阅读:
    第四次作业--项目选题报告(团队)
    第三次作业--团队展示(团队)
    第二次作业——个人项目实战
    2017软件工程实践
    Unity3D游戏开发——显示物品的仓库UI
    Unity3D游戏开发——物品存储:List与Dictionary
    Unity3D游戏开发——编程实现游戏管理器
    Unity3D游戏开发——访问集中式共享模块的设计模式
    Unity3D游戏开发——收集当前关卡游戏中分散的物件
    福州大学软工1816 K 班助教总结
  • 原文地址:https://www.cnblogs.com/a249189046/p/9728394.html
Copyright © 2011-2022 走看看