hdu2087 剪花布条
剪花布条
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 28776 Accepted Submission(s): 17615
Problem Description
一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢?
Input
输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。
Output
输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。
Sample Input
abcde a3
aaaaaa aa
#
Sample Output
0
3
分析:
此题为模式串匹配问题,KMP算法找到“第一个”符合的子串,记住位置,找到剩余子串中符合的“第一个”子串,每次找到计数加一,找不到退出打印结果即可。
ac代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <string.h> 3 4 char a[1000+50]; 5 char b[1000+50]; 6 int next[10000+50]; 7 int Kmp(int lena,int lenb,int pos); 8 void get_Next(int lenb); 9 10 int main() 11 { 12 while(scanf("%s", a)) 13 { 14 int res=0; 15 if(a[0]=='#') 16 break; 17 scanf("%s", b); 18 int lena=strlen(a); 19 int lenb=strlen(b); 20 get_Next(lenb); 21 for(int pos=0;pos<lena;pos++) 22 { 23 int temp=Kmp(lena, lenb, pos); 24 if(temp!=-1) ///不等于一则还有子串,结果加一后继续查找 25 { 26 res++; 27 pos = temp+lenb; 28 } 29 else ///如果等于-1则表示之后没有与模式串匹配的子串 30 { 31 break; 32 } 33 } 34 printf("%d\n", res); 35 memset(a, '\0', sizeof a); 36 memset(b, '\0', sizeof b); 37 } 38 return 0; 39 } 40 ///KMP算法 41 int Kmp(int lena,int lenb,int pos) 42 { 43 int i=pos-1,j=0; 44 while(i<lena&&j<lenb) 45 { 46 if(j==-1||a[i]==b[j]) 47 { 48 i++; 49 j++; 50 } 51 else 52 j=next[j]; 53 } 54 if(j==lenb) 55 return i-lenb; 56 else 57 return -1; 58 } 59 ///获取前缀数组 60 void get_Next(int lenb) 61 { 62 int i=0,j=-1; 63 next[0]=-1; 64 while(i<lenb-1) 65 { 66 if(j==-1||b[i]==b[j]) 67 { 68 i++; 69 j++; 70 next[i]=j; 71 } 72 else 73 j=next[j]; 74 } 75 }