• 【Luogu P4824】[USACO15FEB]Censoring S


    链接:

    洛谷

    题目大意:

    (S) 中从头开始寻找屏蔽词,一旦找到一个屏蔽词,就删除它,然后又从头开始寻找(而不是接着往下找)。

    只有一个屏蔽词。

    正文:

    单模式串匹配,考虑用 KMP。如果匹配不到,则入栈;否则记录一下当前位置,并将当前匹配到的位置 (i) 往前移,并出栈。

    但是这么做有一个弊端:这不是链表,如果贸然把 (i) 往前移会死循环。所以考虑用链表维护,在往前移时,指针往后指。

    代码:

    const int N = 1e6 + 10;
    
    inline ll Read()
    {
    	ll x = 0, f = 1;
    	char c = getchar();
    	while (c != '-' && (c < '0' || c > '9')) c = getchar();
    	if (c == '-') f = -f, c = getchar();
    	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
    	return x * f;
    }
    
    int n; 
    char s[N], t[N], ans[N]; 
    int nxt[N], to[N], a[N];
    int top, m;
    
    struct Stack
    {
    	int i, j;
    }stk[N];
    
    void KMP(char *s, char *t, int op = 1)
    {
    	int j = 0, Slen = strlen(s), Tlen = strlen(t);
    	for (int i = op; i < Tlen; i = to[i])
    	{
    		while (j && t[i] != s[j]) j = nxt[j];
    		if (t[i] == s[j]) j++;
    		if (op) nxt[i + 1] = j;
    		else
    		{
    			if (j == Slen)
    				a[i] = Slen, top -= Slen - 1, to[stk[top].i] = i + 1, i = stk[top].i, j = stk[top].j;
    			else stk[++top] = (Stack){i, j};
    		}
    	}
    	if (!op)
    	{
    		for (int i = Tlen - 1, Dlt = 0; ~i; i--)
    		{
    			Dlt += a[i];
    			if (Dlt) Dlt--;
    			else ans[m++] = t[i];
    		}
    		for (int i = m - 1; ~i; i--) printf("%c", ans[i]);
    	}
    }
    
    int main()
    {
    	scanf("%s%s", t, s); n = strlen(t);
    	for (int i = 0; i < n; i++) to[i] = i + 1;
    	KMP(s, s);
    	KMP(s, t, 0);
    	return 0;
    }
    
  • 相关阅读:
    form表单提交json格式数据
    docker搭建jenkins
    consul搭建服务注册和
    docker创建mysql镜像
    Swagger入门
    net coer log4+ELK搭建
    log4配置
    netcore autofac依赖注入
    netcore 跨域
    netcore 读取配置文件
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/14842086.html
Copyright © 2020-2023  润新知