zoukankan      html  css  js  c++  java
  • 1476E.Pattern Matching(字典树+拓扑排序)

    您将得到n个模式p1,p2,…,pn和m个字符串s1,s2,…,sm。每个模式pi包含k个字符,这些字符可以是小写拉丁字母或通配符(用下划线表示)。所有模式都是成对的。每个字符串sj包含k个小写拉丁字母。

    如果bi从1到k中的每个i是通配符或bi = ai,则字符串a与模式b匹配。

    要求您以第j个字符串匹配的第一个模式为p [mtj]的方式重新排列模式。您可以保留模式顺序不变。

    可以进行这样的重新排列吗?如果可以,则打印任何有效订单。

    题意不太好懂,懂了之后就是常规套路,从哪里跌倒就从哪里爬起来。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+100;
    int n,m,k;
    string p[maxn];
    struct node {
        string s;
        int tk,p;
        bool operator < (const node &r) const {
            return tk<r.tk;
        }
    }Node[maxn];
    vector<int> g[maxn];
    vector<int> l[maxn];
    int inDegree[maxn];
    int Trie[maxn][30];
    int tot=0;
    void insert (int i,int pp,int rt) {
        //p表示插入起点
        if (pp==p[i].size()) {
            g[rt].push_back(i);
            return;
        } 
        if (p[i][pp]=='_') {
            for (int j=0;j<26;j++) {
                if (!Trie[rt][j]) Trie[rt][j]=++tot;
                insert(i,pp+1,Trie[rt][j]);
            }
        }
        else {
            int tt=p[i][pp]-'a';
            if (!Trie[rt][tt]) Trie[rt][tt]=++tot;
            insert(i,pp+1,Trie[rt][tt]);
        }
    }
    int find (int k) {
        int rt=0;
        for (int i=0;i<Node[k].s.size();i++) {
            int x=Node[k].s[i]-'a';
            if (!Trie[rt][x]) return 0;
            rt=Trie[rt][x];
        }
        l[k]=g[rt];
        return 1;
    } 
    int main () {
        scanf("%d%d%d",&n,&m,&k);
        for (int i=1;i<=n;i++) cin>>p[i];
        for (int i=1;i<=m;i++) cin>>Node[i].s>>Node[i].tk,Node[i].p=i;
        for (int i=1;i<=n;i++) insert(i,0,0);
        for (int i=1;i<=m;i++) {
            int x=find(i);
            if (x==0) {
                return printf("NO"),0;
            }
        }
        //每个字符串有对应的匹配集合l(i)
        //每个字符串第一个匹配的串应当是p(tk)
        //每个字符串的匹配集合,p(tk)和剩下的串连单向边
        //做拓扑排序
        for (int i=0;i<1e6;i++) g[i].clear();
        for (int i=1;i<=m;i++) {
            int f=0;
            for (int j=0;j<l[i].size();j++) if (l[i][j]==Node[i].tk) f=1;
            if (!f) return printf("NO
    "),0;
            for (int j=0;j<l[i].size();j++) {
                if (l[i][j]==Node[i].tk) continue;
                g[Node[i].tk].push_back(l[i][j]);
                inDegree[l[i][j]]++;
            } 
        }
        vector<int> ans;
        queue<int> q; 
        for (int i=1;i<=n;i++) if (inDegree[i]==0) q.push(i); 
        while (q.size()) {
            int u=q.front();
            q.pop();
            ans.push_back(u);
            for (int i=0;i<g[u].size();i++) if (--inDegree[g[u][i]]==0) q.push(g[u][i]);
        }
        if (ans.size()!=n) return printf("NO
    "),0;
        printf("YES
    ");
        for (int i=0;i<ans.size();i++) printf("%d ",ans[i]);
    }
  • 相关阅读:
    Ajax基础:3.Json
    Head First Design Patterns State Pattern
    Head First Design Patterns Template Method Pattern
    Articles For CSS Related
    Head First Design Patterns Decorator Pattern
    代码审查工具
    How To Be More Active In A Group
    Head First Design Patterns Factory Method Pattern
    Head First Design Patterns Composite Pattern
    Tech Articles
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14349357.html
Copyright © 2011-2022 走看看