Codeforces Round #434 (Div. 2, )-字典树&好题&板子-Polycarp's phone book

来源:互联网 发布:中超数据库 编辑:程序博客网 时间:2024/06/10 02:20

http://codeforces.com/contest/861/problem/D
给定n个9位长的数字。
问你最短的他的子串,并且这个子串没有在其他字符串中出现过。
方法:字典树把 所有字符串的所有后缀加进去,然后统计的时候,把当前要 做的 字符串的所有 后缀删掉,然后再再当前这个树上 查询没有出现的 最短的 这些后缀的 前缀。
(所有子串都可以表示为 母串某一个后缀的前缀。)

#include <bits/stdc++.h>/* 策略(我也没见过这种霸气的操作啊)   维护每一个字符串的所有后缀,   然后查找的时候,再把他的后缀删除了,   网上找了一套 题解,当模板。。   query和  主函数是我自己写的。*/using namespace std;int mx;char a[70010][10],temp[10],ans[10];int len2;struct trie{    trie *next[10];    int cnt;    trie()    {        memset(next,0,sizeof(next));        cnt=0;    }};trie *root;void insert(char *s){    trie *p=root;    int i,k;    for(i=0;s[i]!='\0';++i)    {        k=s[i]-'0';        if(p->next[k]==NULL)            p->next[k]=new trie();        p=p->next[k];        p->cnt++;    }}void Delete(char *s){    trie *p = root;    int i,k;    for(i=0;s[i]!='\0';i++)    {        k = s[i]-'0';        p = p->next[k];        p->cnt--;    }}void del(trie *p){    for(int i=0;i<10;i++)        if(p->next[i]!=NULL)            del(p->next[i]);    free(p);}void query(char *s){    //memset(temp,0,sizeof(temp));    trie *x=root;    int len1=0;    for(int i=0;s[i]!='\0';i++){        temp[len1++]=s[i];        x=x->next[s[i]-'0'];        if(x->cnt==0){           if(len1<=len2){             temp[len1]='\0';             strcpy(ans,temp);             len2=len1;             break;           }        }    }}int main(){   int m;    scanf("%d",&m);    //getchar();    root=new trie();    for(int i=0;i<m;i++){        scanf(" %s",a[i]);        for(int j=0;j<9;j++){            insert(a[i]+j);        }    }    len2=1e7;    for(int i=0;i<m;i++){        len2=1e7;        for(int j=0;j<9;j++)            Delete(a[i]+j);        for(int j=0;j<9;j++)            query(a[i]+j);        for(int j=0;j<9;j++)            insert(a[i]+j);            //cout<<len2<<endl;     printf("%s\n",ans);    }   // cout<<len2<<endl;    return 0;}
阅读全文
0 0
原创粉丝点击