zoukankan      html  css  js  c++  java
  • hunnu11544:小明的烦恼——找字符串

    Problem description
      小明是个非常优秀的同学。他除了特别公正外,他也非常细心,当然老师肯定也知道,这不,老师又有事情找他帮忙了。老师每周都会给他一个字符串A。然后问小明“A字符串的循环移位产生的全部字符串中,字典序最小的是哪个”。于是小明屁颠屁颠的一个一个比对,可是长久下来,小明实在是受不了了,所以他想请你帮帮他。

    相同,你帮他解决。你就会多AC一个题目。 
    Hint:
    假设A字符串为bcda,那么其全部的循环移位的新字符串有cdab。dabc,abcd。和他自己bcda一共四个,然后在这四个中。字典序最小的为abcd,那么输出这个字符串中的第一次字符在原字符串中的位置。为3,假设有多个结果,输出数字最小的。 

    Input
      输入有T组, 以后每组第一行有一个字符串S。长度<=5000000,都是小写字母。
    Output
      对于每个case。输出结果。
    Sample Input
    4
    bcda 
    aaa
    a
    adab
    Sample Output
    3
    0
    0
    2
    Problem Source

      HUNNU Contest 

    //i,j一開始指向第一和第二个字符,k代表i,j開始的字符串最长匹配的长度


    比如 abcdabbcabdc

    第一个a位置为0,第二个a位置为4。第三个位置为8

    如果i=0,j=4的时候(这里我们仅仅是如果的一个中间过程)

    l相应字符相等,k=1

    那么i+k,j+k就是第二个位置,也相等。k=2,匹配长度为2

    可是第三个 s[i+k]>s[j+k]

    那么两者比較的字典序最小的是j所指的位置,j要保留。i肯定不是字典序最小的,所以i直接偏移到i+k的后面去

    反之亦然

    最后我们找i,j最小的就可以

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <stack>
    #include <queue>
    #include <map>
    #include <set>
    #include <vector>
    #include <math.h>
    #include <bitset>
    #include <algorithm>
    #include <climits>
    #include <time.h>
    using namespace std;
    
    #define LS 2*i
    #define RS 2*i+1
    #define UP(i,x,y) for(i=x;i<=y;i++)
    #define DOWN(i,x,y) for(i=x;i>=y;i--)
    #define MEM(a,x) memset(a,x,sizeof(a))
    #define W(a) while(a)
    #define gcd(a,b) __gcd(a,b)
    #define LL long long
    #define N 100000
    #define MOD 1000000007
    #define INF 0x3f3f3f3f
    #define EXP 1e-8
    
    char str[5000005];
    
    int main()
    {
        int i,j,k,len,minn,t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%s",str);
            len = strlen(str);
            i = 0,j = 1,k = 0;
            while(i<len&&j<len&&k<len)
            {
                int t = str[(i+k)%len]-str[(j+k)%len];//取模解决循环移位
                if(t==0) k++;//相等,匹配长度+1
                else
                {
                    if(t>0)
                        i+=k+1;//此时s[i+k]>s[j+k]。i相应的位置肯定不是最大的串,直接移动到匹配子串末尾
                    else
                        j+=k+1;
                    if(i == j)//指向同一个位置,j偏移
                        j++;
                    k = 0;//匹配长度从0開始
                }
            }
            printf("%d
    ",min(i,j));
        }
    
        return 0;
    }
    


  • 相关阅读:
    Asp.Net Core Web应用程序—探索
    C# -Asp.Net.SignalR.Core之Hub
    C#净化版WebApi框架
    C#-Xamarin的Activity传值与Fragment引用
    C#-Xamarin利用ZXing.Net.Mobile进行扫码
    Junit4 架构设计系列(1): Request,ClassRequest 和 RunnerBuilder
    非常好用的正则表达式"\s+"
    简单易懂, JUnit 框架问答
    JUnit扩展:引入新注解Annotation
    让你的自动化代码更健壮
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7043839.html
Copyright © 2011-2022 走看看