Keep Deleting [zoj 3643]
模拟栈
View Code
const int MM = 555555; #define debug puts("wrong") int to[MM], cnt, ans; char str[MM], ch[MM]; char st[MM]; int top; void solve() { int i,j,k, n=strlen(str+1), m=strlen(ch+1); ans=0; top=0; str[0]='#'; for(i=1;i<=m;i++) { if(ch[i]==str[n]) { for(j=n-1;j>0;j--) if((top+j-n)<0 || str[j]!=st[top+j-n]) break; if(j==0) {ans++;top=top-n+1;} else st[top++]=ch[i]; } else st[top++]=ch[i]; } printf("%d\n",ans); } int main() { while(scanf("%s%s",str+1,ch+1)!=EOF) solve(); return 0; } /* aa aaaa */
貌似能构造出一组,如:abbbbbb...b(255个b), bbbbb...b(最大长度)来卡掉我上面的栈模拟, 最坏复杂度O(N*M)。
可以结合KMP和栈模拟,stack 中存的是每个不匹配位置的fail。
View Code
const int MM = 555555; #define debug puts("wrong") int to[MM], cnt, ans; char str[MM], ch[MM]; int st[MM]; int top; int fail[MM]; void get_next(int n) { int i, j=-1; for(fail[0]=-1, i=1;i < n; i++) { while(j>=0 && str[i]!=str[j+1]) j=fail[j]; if(str[j+1]==str[i]) j++; fail[i]=j; } } void solve() { int i,j,k, n=strlen(str), m=strlen(ch), tmp; ans=0; top=0; j=-1; get_next(n); st[top++]=-1; // for(i=0;i<n;i++) printf("%d ",fail[i]); printf("\n"); for(i=0;i<m;i++) { j=st[top-1]; while(j>=0 && ch[i]!=str[j+1]) j=fail[j]; if(ch[i]==str[j+1]) j++; if(j==n-1) {ans++; top=top-n+1;} else st[top++]=j; // printf("%d ",i); for(j=0;j<top;j++) printf("%d ",st[j]); printf("\n"); } printf("%d\n",ans); } int main() { while(scanf("%s%s",str,ch)!=EOF) solve(); return 0; } /* aa aaaa */