病毒 x

 

 

04:病毒

总时间限制: 
1000ms
 
内存限制: 
65535kB
描述

    有一天,小y突然发现自己的计算机感染了一种病毒!还好,小y发现这种病毒很弱,只是会把文档中的所有字母替换成其它字母,但并不改变顺序,也不会增加和删除字母。

  现在怎么恢复原来的文档呢!小y很聪明,他在其他没有感染病毒的机器上,生成了一个由若干单词构成的字典,字典中的单词是按照字母顺序排列的,他把这个文件拷贝到自己的机器里,故意让它感染上病毒,他想利用这个字典文件原来的有序性,找到病毒替换字母的规律,再用来恢复其它文档。

  现在你的任务是:告诉你被病毒感染了的字典,要你恢复一个字母串。

 

 

输入
virus.in
第一行为整数K(≤50000),表示字典中的单词个数。
以下K行,是被病毒感染了的字典,每行一个单词。
最后一行是需要你恢复的一串字母。
所有字母均为小写。
输出
virus.out
输出仅一行,为恢复后的一串字母。当然也有可能出现字典不完整、甚至字典是错的情况,这时请输出一个0。
样例输入
6
cebdbac
cac
ecd
dca
aba
bac
cedab
样例输出
abcde
 1 #include <iostream>
 2 using namespace std;
 3 
 4 #include <cstdio>
 5 #include <cstdlib>
 6 #include <cmath>
 7 
 8 int qm[27],sd[27],dy[27];// qm记录入度 
 9 string s[50001];
10 int next[1000],back[1000],last[1000];//邻接表元素 
11 bool yt[27][27];// 判断字母应该出现的顺序 
12 int tot,cmax;
13 bool cx[27];
14 
15 void add_edge(int a,int b)
16 {
17     tot++;
18     next[tot]=b;// b 必须要在 a 之后才能出现 
19     back[tot]=last[a];// 指针指向下一条边 
20     last[a]=tot;// 相当于head指针 
21 }
22 
23 void dfs(int x,int t)// t表示字母个数 
24 {
25     if (t>sd[x]) sd[x]=t; //sd表示与x相关的字母数量 
26     int i=last[x];
27     while (i!=0)// 枚举与x+96相关的所有字母 
28     {
29         int v=next[i];
30         if (sd[v]<=t) dfs(v,t+1); 
31         i=back[i];
32     }
33 }
34 
35 void error()
36 {
37     cout<<"0";
38     exit (0);// 强制退出程序 相当于return 0(不过要比return 0凶一点嘻嘻); 
39 }
40 
41 int main()
42 {
43     int k;
44     cin>>k;
45     for (int i=0; i<=k; i++)
46         getline(cin,s[i]);
47     for (int i=2; i<=k; i++)// 因为判断是把当前字符串与上一个字符串进行比较 
48     {
49         int l1=s[i-1].size(); 
50         int l2=s[i].size(); 
51         for (int j=0; j<=min(l1,l2)-1; j++) //比较到较短的长度 
52         {
53             int t1=s[i-1][j]-96;
54             int t2=s[i][j]-96;
55             cmax=max(t1,max(t2,cmax));// 找到所有输入的最大值 
56             if (t1==t2) continue;  
57             if (yt[t2][t1]) error();//t1必须在t2之前  
58             qm[t2]++;// 入度   拓扑排序 
59             yt[t1][t2]=true;
60             add_edge(t1,t2);
61             break;
62             // 如果找到t1<t2的元素直接退出 因为字典序只比较第一个不相同的元素 
63         }
64     }
65     for (int i=1; i<=cmax; i++)
66     {
67         if (qm[i]==0)  //如果他的入度为0 
68         dfs(i,1);
69     }//统计与所有字母相关的字母的数量 
70     string que,ans="";
71     getline(cin,que);// 输入待处理的字符串 
72      for (int i=0; i<=que.size()-1; i++) 
73     {
74         if (cx[sd[que[i]-96]]) error();
75         cx[sd[que[i]-96]]=true; //进行判重
76           if (sd[que[i]-96]==0) error();//如果没有找到可以匹配的元素 
77         ans=ans+(char (sd[que[i]-96]+96));
78     }
79     cout<<ans;
80     return 0; 
81 }

没太看懂

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<stack>
  5 #include<cstdlib> 
  6 #include<cmath>
  7 
  8 const int MAXN=50000;
  9 using namespace std;
 10 
 11 string a[MAXN];
 12 int maxnlength;
 13 
 14 struct node
 15 {
 16     int u;
 17     int v;
 18     int w;
 19     int next;
 20 }edge[MAXN];
 21 
 22 int rudu[MAXN];
 23 int head[MAXN];
 24 int num=1;
 25 int ans[10001];//保存拓扑排序的结果 
 26 int now=1;
 27 int n;
 28 int maxnchar=0;
 29 int map[101][101];
 30 
 31 void topsort()
 32 {
 33     stack<int>s;
 34     for(int i=1;i<=maxnchar;i++)
 35     {
 36         if(rudu[i]==0)
 37         {
 38             s.push(i);
 39             ans[now]=i;
 40             now++;
 41         }
 42     }
 43     int flag=0;
 44     while(s.size()==1)
 45     {
 46         if(s.size()>1)
 47         {
 48             flag=1;
 49             break;
 50         }
 51         int p=s.top();
 52         s.pop();
 53         for(int i=head[p];i!=-1;i=edge[i].next)
 54         {
 55             rudu[edge[i].v]--;
 56             if(rudu[edge[i].v]==0)
 57             {
 58                 s.push(edge[i].v);
 59                 ans[now]=edge[i].v;
 60                 now++;
 61             }
 62         }
 63     }
 64     if(flag==1)
 65     {
 66         printf("0\n");
 67         exit(0);
 68     }
 69 }
 70 
 71 int main()
 72 {
 73     
 74     scanf("%d",&n);
 75     for(int i=1;i<=n;i++)head[i]=-1;
 76     for(int i=1;i<=n;i++)
 77     {
 78         cin>>a[i];
 79         if(a[i].length()>maxnlength)
 80         maxnlength=a[i].length();
 81         for(int j=1;j<=a[i].length();j++)
 82         {
 83             if(a[i][j]-96>maxnchar)
 84             maxnchar=a[i][j]-96;
 85         }
 86     }
 87     int flag2=0;
 88     for(int i=2;i<=n;i++)
 89     {
 90         int j=i-1;
 91             for(int k=0;k<=min(a[i].length()-1,a[j].length()-1);k++)
 92             {
 93                 if(a[j][k]!=a[i][k])
 94                 {
 95                     if(map[a[j][k]-96][a[i][k]-96]==1||map[a[i][k]-96][a[j][k]-96]==1)
 96                     {
 97                         printf("0\n");
 98                         return 0;
 99                     }
100                     edge[num].u=a[j][k]-96;
101                     edge[num].v=a[i][k]-96;
102                     edge[num].next=head[edge[num].u];
103                     head[edge[num].u]=num++;
104                     rudu[a[i][k]-96]++;
105                     flag2=1;
106                     map[a[j][k]-96][a[i][k]-96]=1;
107                     break;
108                 }
109             }
110             //if(flag2==1)break;
111     }
112     topsort();
113     char sr[101];
114     char huiche[1];
115     gets(huiche);
116     gets(sr);
117     int l=strlen(sr);
118     //int srl=sr.length();
119     for(int i=0;i<=l;i++)
120     {
121         if(sr[i]-96>maxnchar)
122         {
123             printf("0\n");
124             return 0;
125         }
126     }
127     for(int i=0;i<=l;i++)
128     {
129         for(int j=1;j<=now-1;j++)
130         {
131             if(ans[j]==sr[i]-96)
132             {
133                 printf("%c",char(j+96));
134             }
135         }
136     }
137     return 0;
138 }

 

posted @ 2017-04-17 19:31  夜雨声不烦  阅读(300)  评论(0编辑  收藏  举报