• [Usaco2008 Dec]Secret Message 秘密信息


    给n条01信息以及m条01密码,求对于每条密码,有多少条信息与他的最长公共前缀=min(密码长度,该条信息长度)

    Sample Input
    4 5
    3 0 1 0
    1 1
    3 1 0 0
    3 1 1 0
    1 0
    1 1
    2 0 1
    5 0 1 0 0 1
    2 1 1
    INPUT DETAILS:
    Four messages; five codewords.
    The intercepted messages start with 010, 1, 100, and 110.
    The possible codewords start with 0, 1, 01, 01001, and 11.

    Sample Output
    1
    3
    1
    1
    2
    //
    0 matches only 010:
    1 match 1 matches 1, 100, and 110:
    01 matches only 010
    01001 matches 010:
    11 matches 1 and 110

    Sol:
    对于每个TRIE中的结点进行标记
    记下其被经过多少次,记为Longer
    再记下对于单词的结束点,标记其次数为Shorter
    然后让当前的字符串到TRIE中去跑,走到某个点时,如果当前字符串还没到最后一个字符,
    则加上这个结点的Shorter标记(这个点表示单词已走完,但当前字符串没走完,所以是当前字符串的前缀)
    否则加上其Longer标记(说有当前字符串已走完,字符仍在延伸,说明当前字符串是其前缀)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define maxn 500500
    int n,m,tmp,cnt;
    int son[maxn][2],a[10100],longer[maxn],shorter[maxn];
      
    void insert()
    {
        int p=0;
        for (int i=1;i<=tmp;i++)
        {
            if (!son[p][a[i]])
                son[p][a[i]]=++cnt;
            p=son[p][a[i]];
            longer[p]++;
            //p这个点被经过多少次 
        }
        shorter[p]++;
        //以P为结束端点的单词有多少个 
    }
      
    void work(){
        int p=0,ans=0;
        for (int i=1;i<=tmp;i++)
        {
            if (!son[p][a[i]])
                break;
            if (i<tmp)
                ans+=shorter[son[p][a[i]]];
                //如果i<tmp说明当前读的单词还没有走完,此时经过的点
                //加上其shorter标记,说是这些单词都是他的前缀 
            else
                ans+=longer[son[p][a[i]]];
                //否则说是当前读的单词已走完,此时经过的点被经过了
                //多少次,就说当前单词是其前缀 
            p=son[p][a[i]];
        }
        printf("%d
    ",ans);
    }
      
    int main(){
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&tmp);
            for (int j=1;j<=tmp;j++)
                 scanf("%d",&a[j]);
            insert();
        }
        for (int i=1;i<=m;i++)
        {
            scanf("%d",&tmp);
            for (int j=1;j<=tmp;j++)
                 scanf("%d",&a[j]);
            work();
        }
        return 0;
    }
  • 相关阅读:
    20179311《网络攻防实践》第八周作业
    20179311《网络攻防实践》第七周作业
    20179311《网络攻防实践》第六周作业
    20179311《网络攻防实践》第五周作业
    20179311《网络攻防实践》第四周作业
    20179311《网络攻防实践》第三周作业
    20179311《网络攻防实践》第二周作业
    python的 Function Annotations学习笔记
    测试如何快速了解一个产品、需求、任务(海盗派测试分析)
    基于Jmeter和Jenkins搭建性能测试框架
  • 原文地址:https://www.cnblogs.com/cutemush/p/12411837.html
Copyright © 2020-2023  润新知