zoukankan      html  css  js  c++  java
  • 字符串最小表示法

    模板:

    int min_max_express(char *s,int len,bool flag){//最小表示法和最大表示法写到一块儿了 
        int i=0,j=1,k=0; 
        while(i<len&&j<len&&k<len){//一次就能够找着 
            int t=s[(j+k)%len]-s[(i+k)%len];//比较两个字符 
            if(t==0)k++;//相等,就后移比较下一个字符 
            else{
                if(flag){//最小表示法 
                    if(t>0)j+=k+1; //+(k+1)相当于直接把相等的跳过 
                    else i+=k+1;
                }else{//最大表示法 
                    if(t<0) j+=k+1; 
                    else i+=k+1;
                }
                if(i==j)j++;
                k=0; 
            } 
        }
        return min(i,j);
    }
    View Code

    最小表示法的意思:

    对于一个字符串S,求S的循环的同构字符串S’中字典序最小的一个。由于语言能力有限,还是用实际例子来解释比较容易:

     设S=bcad,且S’是S的循环同构的串。S’可以是bcad或者cadb,adbc,dbca。而且最小表示的S’是adbc。 对于字符串循环同构的最小表示法,其问题实质是求

    S串的一个位置,从这个位置开始循环输出S,得到的S’字典序最小。

    博客:

    例题:hdu 3374

    代码:

    #include<stdio.h>
    #include<algorithm>
    #include<iostream>
    #include<string.h>
    using namespace std;
    const int max_=1e6+5;
    char str[max_];
    int nex[max_];
    void getnext(int n)
    {
      //  int n=strlen(str);
        int i=0,k=-1;
        nex[i]=-1;
        while(i<n)
        {
            while(k>-1&&str[i]!=str[k])
                k=nex[k];
            nex[++i]=++k;
        }
    }
    int solve(bool f)
    {
        int i=0,j=1,k=0;
        int len=strlen(str);
        while(i<len&&j<len&&k<len)
        {
            int t=str[(j+k)%len]-str[(i+k)%len];
            if(t==0)
                k++;
            else
            {
               if(f)
                {//最小表示法
                    if(t>0)j+=k+1; //+(k+1)相当于直接把相等的跳过
                    else i+=k+1;
                }
               else
                {//最大表示法
                    if(t<0) j+=k+1;
                    else i+=k+1;
                }
                if(i==j)j++;
                k=0;
            }
        }
        return min(i,j);
    }
    int main()
    {
        while(scanf("%s",str)!=EOF)
        {
            int len=strlen(str);
            getnext(len);
            int k=len-nex[len];
            int ans;
            int Min=solve(1);
            int Max=solve(0);
            if(len%k==0)
                ans=len/k;
            else
                ans=1;
            printf("%d %d %d %d
    ",Min+1,ans,Max+1,ans);
        }
    }
    View Code
  • 相关阅读:
    osg::BlendFunc来设置透明度
    LCA(Tarjan)
    CODEVS1073 家族 (并查集)
    CODEVS1533 互斥的数(哈希表)
    2014-12-4
    BZOJ2661 连连看 (费用流)
    2014-11-30
    JAVA语法基础作业——动手动脑以及课后实验性问题
    课后作业01——相加
    再读大道至简第二章
  • 原文地址:https://www.cnblogs.com/linhaitai/p/9917495.html
Copyright © 2011-2022 走看看