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
*/
原文地址:https://www.cnblogs.com/zhang1107/p/3029617.html