zoukankan      html  css  js  c++  java
  • [BFS]luogu P2536 [AHOI2005]病毒检测

    题面

    https://www.luogu.com.cn/problem/P2536

    分析

    考虑建一个像trie的东西,即向下一个节点连代表字母的边

    那么对于 AGCT 就直接向下一个节点连边

    对于 ? 则可以向下一个节点连所有字母的边

    对于 * ,我们采用对通配符的惯用操作,向自己连所有字母的边,即构造自环,表示匹配的时候可以是任意串

    那么匹配的时候,在匹配串里正常移动,模式串里BFS,但是会T

    考虑优化,发现对于匹配串的当前位置转移到下一个位置,在模式串中的每个点只能到达一次

    所以用滚动队列跑BFS,每次扩展状态的时候标记一个 added 数组即可,记得清空

    同时跑到匹配串和模式串的结尾则是一个未知病毒

    代码

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    const int N=510;
    struct Graph {
        int v,w,nx;
    }g[8*N];
    int cnt,list[2*N],gcnt;
    int n,m,ans;
    char s[2*N];
    bool added[2*N];
    
    void Add(int u,int v,int w) {g[++cnt]=(Graph){v,w,list[u]};list[u]=cnt;}
    
    void BFS() {
        queue<int> q[2];int e=0;
        while (!q[0].empty()) q[0].pop();while (!q[1].empty()) q[1].pop();
        q[e].push(0);
        for (int j=1;j<m;j++) {
            memset(added,0,sizeof added);
            while (!q[e].empty()) {
                int u=q[e].front();q[e].pop();
                for (int i=list[u];i;i=g[i].nx)
                    if (g[i].w==s[j]&&!added[g[i].v]) added[g[i].v]=1,q[e^1].push(g[i].v);
            }
            e^=1;
        }
        while (!q[e].empty()) {
            int u=q[e].front();q[e].pop();
            for (int i=list[u];i;i=g[i].nx)
                if (g[i].w==s[m]&&g[i].v==gcnt) return;
        }
        ans++;
    }
    
    int main() {
        scanf("%s",s+1);m=strlen(s+1);
        for (int i=1;i<=m;i++) {
            switch (s[i]) {
                case '?':{
                    Add(gcnt,gcnt+1,'A');Add(gcnt,gcnt+1,'G');Add(gcnt,gcnt+1,'C');Add(gcnt,gcnt+1,'T');gcnt++;
                    break;
                }
                case '*':{
                    Add(gcnt,gcnt,'A');Add(gcnt,gcnt,'G');Add(gcnt,gcnt,'C');Add(gcnt,gcnt,'T');
                    break;
                }
                default:{
                    Add(gcnt,gcnt+1,s[i]);gcnt++;
                    break;
                }
            }
        }
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%s",s+1),m=strlen(s+1),BFS();
        printf("%d
    ",ans);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    v-charts 绘制柱状图、条形图、水球图、雷达图、折线图+柱状图,附官网地址
    vue-cli3 assets目录下的SASS文件中添加背景图片报错Module not found: Error: Can't resolve './@/assets/images/login.png'解决办法
    Vue UI 框架(pc、移动端)
    单页面应用 VS 多页面应用
    DOM重点核心总结
    JS之三种动态创建元素的区别
    DOM节点操作
    自定义属性
    CSS面试题
    CSS中定义变量,并使用变量设置属性值
  • 原文地址:https://www.cnblogs.com/mastervan/p/14598426.html
Copyright © 2011-2022 走看看