HDU 5442 (最小表示法+next数组循环节)

这题比赛20分钟时候看的,最后一分钟A的。。。

原因就是逆着找的时候要是尽可能后面的,比如abab  倒过来是baba 应该是后面这个b,此时这个对应原串的位置更小

所以用Next数组搞一下。

 

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 50000+50; //开两倍的原因是要复制串长
 4 char s[maxn],t[maxn];
 5 char ss[maxn],tt[maxn];
 6 int Next[maxn>>1];
 7 int biggest(int len,char pat[])  //最大表示法
 8 {
 9    //int len = strlen(pat);
10    int i=0,j=1,k=0;
11    while(i<len && j<len && k<len)
12    {
13        int t = pat[(i+k)%len] - pat[(j+k)%len];
14        if(!t) k++;
15        else
16        {
17            if(t>0) j = j+k+1;
18            else i = i+k+1;
19            if(i == j) j++;
20            k = 0 ;
21        }
22    }
23    return i<j?i:j;
24 }
25 void getNext(int len)
26 {
27     int i=0,j=-1;
28     Next[0]=-1;
29     while(i<len)
30     {
31         if(j==-1||t[i]==t[j])
32         i++,j++,Next[i]=j;
33         else
34         j=Next[j];
35     }
36 }
37 int main()
38 {
39         int test;
40         cin>>test;
41         while(test--)
42         {
43                 memset(t,0,sizeof(t));
44                 memset(s,0,sizeof(s));
45                 int len;
46                 cin>>len;
47                 cin>>s;
48 
49                 for(int j = 0, i=len-1;i>=0;i--)
50                         t[j++]=s[i];
51                 t[len]='\0';
52                 getNext(len);
53                 int k1 = biggest(len,s);
54                 int k2 = biggest(len,t);
55                 int kk1=k1,kk2=k2;
56                 for(int i = 0;i < len;i++){
57                         ss[i]=s[k1%len];
58                         k1++;
59                 }
60                 for(int i = 0;i < len;i++)
61                 {
62                         tt[i]=t[k2%len];
63                         k2++;
64                 }
65                 int sum=len-Next[len];
66                 int ans=0;
67                 if(len%sum==0) {ans = len/sum;  kk2+=(ans-1)*sum;}
68                 int tip=0;
69                 ss[len]='\0';tt[len] = '\0';
70                 if(strcmp(ss,tt)>0)  ans = kk1+1;
71                 if(strcmp(ss,tt)<0)  ans=(len-kk2),tip=1;
72                 if(strcmp(ss,tt)==0)
73                 {
74                         if((kk1+1)<(len-kk2)) ans=kk1+1;
75                         if((kk1+1)>(len-kk2)) ans=(len-kk2),tip=1;
76                         if((kk1+1)==(len-kk2)) ans=kk1+1;
77                 }
78                 cout<<ans<<" "<<tip<<endl;
79         }
80 }
View Code

 

posted on 2015-09-13 19:14  小松song  阅读(143)  评论(0)    收藏  举报

导航