后海的槐树时而掉下一些丝状的莫名的东西,日光慢悠悠的溜了过去,时间过得很慢,却又很快。
好吧,我承认,我也文艺了一把。
不过说的也很对,时间过得很慢,却又很快。。
转眼已是大三,哦,不再大三了,大四啦。
大学的最后一个暑假仍然是在机房度过,苦逼的生活,艰苦的岁月我们还是熬了下来。
希望能熬完最后一个暑假,做完最后一些比赛,然后挥手告别我的acm,告别它陪我的那段青葱岁月,无悔的时光。
好啦,这只是后话啦。
扯回来。。。。
最小表示法
今天大一的学弟问我最小表示法,我表示当时就凌乱了,从来没听说过啊有木有。。。
然后就赶快上网搜了一下:
http://wenku.baidu.com/view/976dc391daef5ef7ba0d3ca5.html
感觉处理一些问题还是比较简单的,不过相当的有局限性。。。
此题先用最小表示法和最大表示法找到字典序最小和最大的字符串。
然后用kmp计算出现的次数。
View Code
1 # include<stdio.h> 2 # include<string.h> 3 # include<stdlib.h> 4 # define N 1000005 5 char s1[2*N],s2[2*N],s[N],ch1[N],ch2[N];; 6 int next[N]; 7 void Gnext(char str[]) 8 { 9 int i,j,len=strlen(str); 10 next[0]=0; 11 j=0; 12 for(i=1;i<len;i++) 13 { 14 while(j>0 && str[j]!=str[i]) j=next[j-1]; 15 if(str[i]==str[j]) j++; 16 next[i]=j; 17 } 18 } 19 int KMP(char *a,char *b) 20 { 21 int i,j,lena,lenb,count; 22 j=0; 23 lena=strlen(a); 24 lenb=strlen(b); 25 count=0; 26 for(i=0;i<lenb;i++) 27 { 28 while(j>0 && a[j]!=b[i]) j=next[j-1]; 29 if(a[j]==b[i]) j++; 30 if(j==lena) {j=next[j-1];count++;} 31 } 32 return count; 33 } 34 int main() 35 { 36 int i,j,len1,len2,len,k,minnum,maxnum,count1,count2; 37 while(scanf("%s",s)!=EOF) 38 { 39 len=strlen(s); 40 strcpy(s1,s); 41 strcat(s1,s); 42 strcpy(s2,s1); 43 i=0;j=1; 44 while(i<=len && j<=len) 45 { 46 for(k=0;k<len;k++) 47 if(s1[i+k]!=s2[j+k]) break; 48 if(k==len) break; 49 if(s1[i+k]>s2[j+k]) i=i+k+1; 50 else j=j+k+1; 51 if(i==j) j++; 52 } 53 if(j<i) i=j; 54 minnum=i+1; 55 for(j=0;j<len;j++) 56 ch1[j]=s1[i+j]; 57 ch1[j]=0; 58 //puts(ch1); 59 60 i=0;j=1; 61 while(i<=len && j<=len) 62 { 63 for(k=0;k<len;k++) 64 if(s1[i+k]!=s2[j+k]) break; 65 if(k==len) break; 66 if(s1[i+k]<s2[j+k]) i=i+k+1; 67 else j=j+k+1; 68 if(i==j) j++; 69 } 70 if(j<i) j=i; 71 maxnum=i+1; 72 for(j=0;j<len;j++) 73 ch2[j]=s1[i+j]; 74 ch2[j]=0; 75 //puts(ch2); 76 77 Gnext(ch1); 78 count1=KMP(ch1,s1); 79 if(minnum==1) count1--; 80 81 Gnext(ch2); 82 count2=KMP(ch2,s1); 83 if(maxnum==1) count2--; 84 printf("%d %d %d %d\n",minnum,count1,maxnum,count2); 85 } 86 system("pause"); 87 return 0; 88 }