zoukankan      html  css  js  c++  java
  • 最小表示法总结

    问题解决

    一般用于解决一类最小表示或最小串的问题。

    问题引入

    例题:poj1509

    求它的循环串中字典序最小的串的开头。

    问题解决

    暴力

    找到所有的串存下来然后排序,复杂度(Theta(n^2))的。

    诡异做法

    建个后缀自动机然后遍历最小的字母边即可。

    正经一点的

    考虑两个指针(i),(j),一边扫过去的时候暴力求一下(i,j)(lcp)的长度,然后比一下(lcp)后一位,把大的那个指针往后移那么多位即可。

    代码实现

    /*
      mail: mleautomaton@foxmail.com
      author: MLEAutoMaton
      This Code is made by MLEAutoMaton
    */
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<iostream>
    using namespace std;
    #define ll long long
    #define REP(a,b,c) for(int a=b;a<=c;a++)
    #define re register
    #define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    inline int gi(){
    	int f=1,sum=0;char ch=getchar();
    	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    	return f*sum;
    }
    const int N=100010;
    char s[N];int n;
    int main(){
    	int T=gi();
    	while(T--){
    		scanf("%s",s);n=strlen(s);
    		int i=0,j=1;
    		while(i<n && j<n){
    			int k=0;
    			while(k<=n && s[(i+k)%n]==s[(j+k)%n])k++;
    			if(k>n)break;
    			if(s[(i+k)%n]<=s[(j+k)%n])j=j+k+1;
    			else i=i+k+1;
    			if(i==j)j=i+1;
    		}
    		printf("%d
    ",min(i+1,j+1));
    	}
    	return 0;
    }
    
  • 相关阅读:
    图像处理笔记(十)
    图像处理笔记(九):频率域滤波
    图像处理笔记(八)
    图像处理笔记(七)
    图像处理笔记(六):灰度变换与空间滤波
    分布式
    关于python代码是编译执行还是解释执行
    python中的元类metaclass
    Python的函数参数传递
    递推思想
  • 原文地址:https://www.cnblogs.com/fexuile/p/11625861.html
Copyright © 2011-2022 走看看