• POJ 1509 循环同构的最小表示法


     题目大意:

    给定一个字符串,可以把一段尾部接到头部,这样找到一个最小的字符串

    方案一:

    利用循环同构中找最小表示的方法来解决

    论文参考http://wenku.baidu.com/view/438cad13a2161479171128b6.html

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 
     5 using namespace std;
     6 #define N 10005
     7 char s[N];
     8 
     9 inline int minpos(char *s)
    10 {
    11     int l = strlen(s);
    12     int i=0 , j=1 , k=0;
    13     while(i<l&&j<l&&k<l){ //这里k<l是防止出现所有数都一样导致无限循环
    14         if(i == j) j++;
    15         else if(s[(i+k)%l]>s[(j+k)%l]){
    16             i = i+k+1;
    17             k=0;
    18         }
    19         else if(s[(i+k)%l]<s[(j+k)%l]){
    20             j = j+k+1;
    21             k=0;
    22         }
    23         else k++;
    24     }
    25     return min(i , j)+1;
    26 }
    27 
    28 int main()
    29 {
    30    // freopen("a.in" , "r" , stdin);
    31     int T;
    32     scanf("%d" , &T);
    33     while(T--)
    34     {
    35         scanf("%s" , s);
    36         printf("%d
    " , minpos(s));
    37     }
    38     return 0;
    39 }

     后缀自动机写法:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 #include <queue>
     6 using namespace std;
     7 /* run this program using the console pauser or add your own getch, system("pause") or input loop */
     8 #define M 26
     9 #define N 40100
    10 char str[N];
    11 
    12 struct SamNode{
    13     SamNode *son[M] , *f;
    14     int l , s;
    15 };
    16 
    17 struct Sam{
    18     SamNode sam[N] , *root , *last;
    19     int cnt;
    20     
    21     void init(){
    22         cnt = 0;
    23         memset(sam , 0 , sizeof(sam));
    24         root = last = &sam[0];    
    25     }
    26     
    27     void add(int x){
    28         SamNode *p = &sam[++cnt] , *jp=last;
    29         /*
    30         这里p->s = jp->s+1写成p->s = p->l也是一样的,因为对于每次当前的last来说,
    31         l和s的值是一样的,因为每次当前的last都是处于字符串的位置上的
    32         数,不是额外添加的节点 
    33         */ 
    34         p->l = jp->l+1; p->s = jp->s+1;
    35         last = p;
    36         for(; jp&&!jp->son[x] ; jp=jp->f) jp->son[x] = p;
    37         if(!jp) p->f=root;
    38         else{
    39             if(jp->l+1 == jp->son[x]->l) p->f = jp->son[x];
    40             else{
    41                 SamNode *r = &sam[++cnt] , *q = jp->son[x];
    42                 *r=*q;
    43                 r->l = jp->l+1 ; r->s = p->l;
    44                 q->f = p->f = r;
    45                 for(; jp && jp->son[x]==q ; jp=jp->f) jp->son[x]=r;
    46             }
    47         }
    48     }    
    49 }sam;
    50 
    51 int solve(int len)
    52 {
    53     SamNode *cur = sam.root;
    54     for(int i=0 ; i<len ; i++){
    55         for(int j=0 ; j<26 ; j++){
    56             if(cur->son[j]){
    57                 cur = cur->son[j];
    58                 break;
    59             }
    60         }
    61     }
    62     return cur->s-len+1;
    63 }
    64 
    65 int main(int argc, char *argv[]) {
    66 //    freopen("in.txt" , "r" , stdin);
    67 //    freopen("out.txt" , "w" , stdout);
    68     int T;
    69     scanf("%d" , &T);
    70     while(T--){
    71         scanf("%s" , str);
    72         int len = strlen(str);
    73         sam.init();
    74         for(int i=0 ; i<len ; i++)
    75             str[len+i] = str[i];
    76         for(int i=0 ; i<len*2 ; i++)
    77             sam.add(str[i]-'a');
    78         int ret = solve(len);
    79         printf("%d
    " , ret);
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    又开始写代码了
    C# 调用office 2007 及 SaveAsPDFandXPS.exe 将Word、Excel、PPT转换为PDF文件
    64位机子上未能加载集
    在 vs 2003 转 2008 时WEB项目不能转换
    【第一弹】测试小学生,终于有博客了
    RobotFramwork + Appium+ Andriod 环境搭建
    写webpart
    backup
    获取MOSS当前登录用户信息
    rotate with different image(轮换显示图片)
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4568786.html
Copyright © 2020-2023  润新知