题意:给出一些字符串,a字符串可以到b字符串,当且仅当在a字符串添加一个字符然后通过排列能够得到b。问最长w1,w2....wm序列,使得wi可以到w[i+1]

题解:将每个字符串各自按字母排序后加入hash表中,并记录该key值对应哪些字符串,枚举每一个字符串删除它的某一位后的字符串是否存在于hash表中,通过那个字符串进行对序列长度的更新。由于字符串长度只有20,所以复杂度很低。

View Code
  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 using namespace std;
  5 const int mod=100007,N=10005,M=1000000;
  6 char hash[mod][40];
  7 int getkey(char s[])
  8 {
  9     int i=0,sum=0;
 10     while(s[i]!='\0')
 11     {
 12         sum=sum*10+s[i];
 13         if(sum>=mod)
 14             sum%=mod;
 15         i++;
 16     }
 17     i=0;
 18     while(hash[sum][0]!='\0'&&strcmp(hash[sum],s)!=0)
 19     {
 20         i++;
 21         sum=sum+i*i;
 22         while(sum<0)
 23             sum+=mod;
 24         if(sum>=mod)
 25             sum%=mod;
 26     }
 27     return sum;
 28 }
 29 int head[mod],pre[N],dp[N],nc;
 30 char sr[N][40];
 31 void dfs(int now)
 32 {
 33     if(pre[now]!=-1)
 34         dfs(pre[now]);
 35     puts(sr[now]);
 36 }
 37 struct Edge
 38 {
 39     int to,next;
 40 } edge[M];
 41 void add(int a,int b)
 42 {
 43     edge[nc].to=b;
 44     edge[nc].next=head[a];
 45     head[a]=nc++;
 46 }
 47 void dfs2(int num)
 48 {
 49     char cs[40],cc[40];
 50     int len,tp=0,key;
 51     strcpy(cs,sr[num]);
 52     len=strlen(cs);
 53     if(len==1)
 54     {
 55         pre[num]=-1;
 56         dp[num]=1;
 57         return;
 58     }
 59     sort(cs,cs+len);
 60     for(int i=0; i<len; i++)
 61     {
 62         memcpy(cc,cs,i*sizeof(char));
 63         memcpy(cc+i,cs+i+1,(len-i-1)*sizeof(char));
 64         cc[len-1]='\0';
 65         if(hash[key=getkey(cc)][0]!='\0')
 66         {
 67             for(int j=head[key]; j!=-1; j=edge[j].next)
 68             {
 69                 int to=edge[j].to;
 70                 if(!dp[to])
 71                     dfs2(to);
 72                 if(tp<dp[to])
 73                     tp=dp[pre[num]=to];
 74             }
 75         }
 76     }
 77     if(tp==0)
 78         pre[num]=-1;
 79     dp[num]=tp+1;
 80 }
 81 int main()
 82 {
 83     int ans=0,id=-1,tp,key,len;
 84     memset(hash,'\0',sizeof(hash));
 85     int n=0;
 86     memset(head,-1,sizeof(head));
 87     memset(pre,-1,sizeof(pre));
 88     nc=0;
 89     char cs[40];
 90     while(scanf("%s",sr[n])!=EOF)
 91     {
 92         len=strlen(sr[n]);
 93         strcpy(cs,sr[n]);
 94         sort(cs,cs+len);
 95         key=getkey(cs);
 96         if(hash[key][0]=='\0')
 97             strcpy(hash[key],cs);
 98         add(key,n);
 99         n++;
100     }
101     memset(dp,0,sizeof(dp));
102     for(int i=0; i<n; i++)
103         if(dp[i]==0)
104         {
105             dfs2(i);
106             if(ans<dp[i])
107                 ans=dp[id=i];
108         }
109     dfs(id);
110     return 0;
111 }