Codeforces contest 861 D 暴力set

原题链接:http://codeforces.com/contest/861/problem/D

大致题意:给出一些字符串,问每一个字符串在这个字符串集合里独有的最小长度的子串。

建立一颗字符串树,然后把每一个字符串的子串都暴力加入进去,同时在每个节点记录第几个字符串经过这个节点。独有的子串就是从根节点到某个只有一个字符串经过的节点,路径构成的子串就是这个字符串的独有的子串。对于最小长度的限制,我是用11进制来更新最小值就可以得到最小长度的独有子串就可以了。

代码:

#include <bits/stdc++.h>

using namespace std;
inline void read(int &x){
    char ch;
    bool flag=false;
    for (ch=getchar();!isdigit(ch);ch=getchar())if (ch=='-') flag=true;
    for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    x=flag?-x:x;
}

inline void read(long long &x){
    char ch;
    bool flag=false;
    for (ch=getchar();!isdigit(ch);ch=getchar())if (ch=='-') flag=true;
    for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    x=flag?-x:x;
}


const int maxn = 71000;
int son[maxn*20][11];
set<int> tree[ maxn*20 ];
int n;
int root, tot;
char s[maxn][15];
int a[maxn][15];

void add(int num, int st ,int ed){
int now=root;
for (int i=st;i<=ed;i++)
    {
        if (son[now][ a[num][ i ] ]==0)
            son[now][ a[num][ i ] ]=++tot;
        tree[now].insert ( num );
        now=son[now][ a[num][ i ] ];
    }
tree[now].insert ( num );
}

long long ans[maxn];

void dfs(int x,long long now){
if( (x!=1) &&  ( tree[x].size()==1 ) )
    {
        int y=*tree[x].begin();
        ans[ y ]=min( ans[ y ] , now );
        if ( ans[ y ] ==0 )
            ans[ y ]=now;
        return ;
    }
for (int i=1;i<=10;i++)
    if ( son[x][i] != 0 )
        dfs(son[x][i],now*11ll+1ll*i);
}

int kkk[ 10000 ];
void out(long long x){
int cnt=0;
while ( x )
    {
        kkk[++cnt]=x%11;
        x=x/11;
    }
for (int i =cnt ; i>=1;i--)
    printf("%d",kkk[i]-1);
puts("");
}

int main(){
    read(n);
    for (int i=1;i<=n;i++)
    {
        gets(s[i]);
        for (int j=0;j<9;j++)
            a[i][j]=s[i][j]-'0'+1;
    }
    /*
    for (int i=1;i<=n;i++)
        {
            for (int j=0;j<9;j++)
                printf("%d ",a[i][j]);
            puts("");
        }
    */
    root=1,tot=1;
    for (int i=1;i<=n;i++)
    {
        for (int j=0;j<9;j++)
            for (int k=j;k<9;k++)
                add( i ,j ,k );
    }
    for (int i=1;i<=n;i++)
        ans[i]=0;
    dfs(1,0ll);
    for (int i=1;i<=n;i++)
        {
            out(ans[i]);
            //printf("%I64d\n",ans[ i ] );
        }
    return 0;
}



猜你喜欢

转载自blog.csdn.net/u012602144/article/details/78020773