• hdu 5442 Favorite Donut 最大表示法+KMP


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5442

    题意:

    有一个由小写字母组成的字符串(长度为n),首尾相接,求顺时针转和逆时针转的情况下,长度为n的最大字典序的字符串的首位的位置。

    如果顺时针和逆时针求得的字符串相同,则选择开始位置较前的,如果开始位置也相同,则选择顺时针的。

    如abcd,那么顺时针可以是abcd,bcda,cdab,dabc.逆时针可以是adcb,dcba,cbad,badc.

    思路:

    顺时针的情况下,直接求最大字典序的位置。逆时针的情况下,由于求最大字典序的串与原串对应位置的编号发生变化,

    所以求得位置后,得到字典序最大的字符串,再用kmp找出该字符串在母串中出现的所有位置,取最靠前的位置。

    然后把顺时针和逆时针的情况进行比较。

      1 #include<iostream>  
      2 #include<string>   
      3 #include<cstring>  
      4 #include<cstdio>  
      5 using namespace std;  
      6 int n;
      7 char S[20010*2];
      8 int Next[1000005];
      9 char P[20010*2];
     10 int idb[20010*2];
     11 int bpos1;
     12 void getNext(char* S,int* Next){ 
     13     int n=strlen(S); 
     14     Next[0]=Next[1]=0; 
     15     for(int i=1; i<n; ++i){ 
     16         int j=Next[i]; 
     17         if(j && S[i]!=S[j]) j=Next[j]; 
     18         Next[i+1] = S[i]==S[j]?1+j:0; 
     19     } 
     20 } 
     21  
     22 void find(char* S,char* P,int* Next){ 
     23     getNext(P,Next); 
     24     int n=strlen(S); 
     25     int m=strlen(P); 
     26     int j=0; 
     27     int cnt=0; 
     28     for(int i=0; i<n; ++i){ 
     29         while(j && S[i]!=P[j]) j=Next[j]; 
     30         if(S[i] == P[j]) ++j; 
     31         if(j==m){ 
     32             if(idb[i-m+1] <= bpos1)
     33             {
     34                 bpos1 = idb[i-m+1];
     35     
     36             }
     37         } 
     38     }  
     39 } 
     40 
     41 int GetMax(char *P)  
     42 {  
     43     int len=n;  
     44     int i=0,j=1,k=0;  
     45     while(i<len&&j<len&&k<len)  
     46     {  
     47         int t=P[(i+k)%len]-P[(j+k)%len];  
     48         if(!t) k++;  
     49         else  
     50         {  
     51             if(t>0) j+=k+1;  
     52             else i+=k+1;  
     53             if(i==j) j++;  
     54             k=0;  
     55         }  
     56     }  
     57     return i<j?i:j;  
     58 } 
     59 char s1[20010];
     60 char s2[20010];
     61 int main()
     62 {
     63     int T;
     64     scanf("%d", &T);
     65     while(T--)
     66     {
     67         scanf("%d", &n);
     68         scanf("%s", s1);
     69         s2[0] = s1[0];
     70         for(int i = 1; i < n; i++) s2[i] = s1[n-i];
     71 
     72         idb[0] = 0;
     73         for(int i = 1; i < n; i++) idb[i] = n-i;
     74         for(int i = n; i < 2*n; i++) idb[i] = idb[i-n];
     75 
     76         int apos = GetMax(s1);
     77         int bpos = GetMax(s2);
     78         int apos1 = apos;
     79 
     80         bpos1 = idb[bpos];
     81           
     82 
     83         string a = "", b = "";
     84         for(int i = apos; i < apos+n; i++) a += s1[i%n];
     85         for(int i = bpos; i < bpos+n; i++) b += s2[i%n];
     86 
     87         for(int i = 0; i < n; i++) S[i] = s2[i];
     88         for(int i = n; i < 2*n; i++) S[i] = s2[i-n];
     89         S[2*n] = '';
     90         
     91         char b1[20010];
     92         for(int i = 0; i < n; i++) b1[i] = b[i];
     93         b1[n] = '';
     94         
     95         find(S, b1, Next);
     96 
     97         if(a>b) printf("%d %d
    ", apos+1, 0);
     98         else if(a < b) printf("%d %d
    ", bpos1+1, 1);
     99         else
    100         {
    101             if(apos1 <= bpos1) printf("%d %d
    ", apos1+1, 0);
    102             else printf("%d %d
    ", bpos1+1, 1);
    103         }
    104 
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    in exists
    oracle 12514文件解决
    oracle11g自动内存管理
    lvs为何不能完全替代DNS轮询
    druid安装
    macbook 安装win7
    GBT MBR
    python的文件操作
    zabbix简易安装指南
    zatree的安装
  • 原文地址:https://www.cnblogs.com/titicia/p/4815348.html
Copyright © 2020-2023  润新知