zoukankan      html  css  js  c++  java
  • ZUCC Flower Name(01字典树)

    Keadin非常苦恼,他马上就要去阿里实习了,但根据公司的规定,在此之前他要为自己取一个在公司内使用的花名,Keadin的取名困难症犯了。他想了一个选出自己花名的规则,但这个规则太复杂所以他想请你帮忙。出于羞耻心和公司的保密要求,Keadin加密了所有字符串,因此你看到的所有字符串都只包含0、1两种字符。

    Keadin决定按照以下规则来选择自己的花名,首先列出N个0字符串S​i​​,表示已经被注册的花名,从1到N编号,之后再列出M个0字符串T​i​​,表示Keadin备选的花名,从1到M编号,他现在想知道,对于他列出的每一个备选花名T​i​​,有多少S​i​​与其互为前缀,互为前缀是指S​i​​是T​i​​的前缀,或者T​i​​是S​i​​的前缀,如果你对前缀的定义不清楚,可以见下面的解释。

    注意:在本题中,花名可以重名。

    对于一个非空字符串A和一个非空字符串B,当且仅当A从末尾删去若干个字符(可以删除0个,即不删)后与B完全相等时,称B为A的前缀,很显然,一个长度为L的字符串A拥有L个不相同的前缀。例如,若字符串A=abcd,则A的前缀有a,ab,abc,abcd四种。

     

    题解:

    对所有的母串建立一颗字典树,然后查询前缀的时候利用这颗字典树就可以大大减少时间和空间复杂度。

    在此之前并没有研究过字典树,只知道大概有这么个东西,考试的时候手写了一遍,最后AC了,终极爆爽。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=5e4+100;
    int N,M;
    string s[maxn];
    string t[maxn];
    int tot=0;
    struct node {
        int num=0;//表示当前节点的字符串数量
        int l=-1;
        int r=-1;//表示左右孩子,左孩子表示0节点,右孩子表示1节点  
    }Node[maxn*10];
    int tt=0;
    int ans;
    void insert (string s) {
        int i;
        int u=0;
        for (int i=0;i<s.length();i++) {
            if (s[i]=='0') {
                if (Node[u].l==-1) Node[u].l=++tot;
                u=Node[u].l;
            }
            else {
                if (Node[u].r==-1) Node[u].r=++tot;
                u=Node[u].r;
            }
        }
        Node[u].num++;
    }
    
    int cal (string s) {
        int ans=0;
        int u=0;
        for (int i=0;i<s.length();i++) {
            if (u==-1) return ans;
            ans+=Node[u].num;
            if (s[i]=='0') 
                u=Node[u].l;
            else 
                u=Node[u].r;
        }
        if (u==-1) return ans;
        ans+=Node[u].num;
        queue<int> q;
        q.push(u);
        while (!q.empty()) {
            int tt=q.front();
            q.pop();
            if (Node[tt].l!=-1) {
                ans+=Node[Node[tt].l].num;
                q.push(Node[tt].l);
            }
            if (Node[tt].r!=-1) {
                ans+=Node[Node[tt].r].num;
                q.push(Node[tt].r);
            }
        }
        return ans;
    }
    int main () {
        scanf("%d",&N);
        Node[tot].num=0;
        Node[tot].l=-1;
        Node[tot].r=-1; 
        for (int i=1;i<=N;i++) {
            cin>>s[i];
            insert(s[i]);
        }
        //if (tot>5e5) while (1);
        scanf("%d",&M);
        for (int i=1;i<=M;i++) {
            cin>>t[i];
            ans=cal(t[i]);
            printf("%d
    ",ans);
        }
        
        
    }
  • 相关阅读:
    django 项目需要注意的一些点
    VUE之路
    Oracle 表格碎片的查看方法
    RHEL 6.x or 7.x 使用分区绑定ASM 磁盘的方法
    RMAN 修复主库 nologging 操作导致物理备库的坏块
    Oracle 数据库19c 回退降级到 11.2.0.4 方案
    如何评估oracle 数据库rman全备和增量备份大小
    在将Oracle GI和DB升级到19c或降级到以前的版本之前需要应用的补丁 (Doc ID 2668071.1)
    Oracle 数据库坏块处理
    opatch auto 安装11.2.0.4.20190115 PSU遇到 OUI-67133: Execution of PRE script failed,with returen value 1 报错
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12974354.html
Copyright © 2011-2022 走看看