zoukankan      html  css  js  c++  java
  • 病毒 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
    ");
     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
    ");
     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
    ");
    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 }

    如果运气好也是错,那我倒愿意错上加错!

    ❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀

  • 相关阅读:
    【POJ1958】汉诺塔+
    hdu 5067(暴力搜索)
    hdu 5063(思路题-反向操作数组)
    hdu 5062(水题)
    hdu 2227(树状数组+dp)
    hdu 5480(维护前缀和+思路题)
    hdu 2492(树状数组)
    hdu 1394(树状数组)
    poj 2299(离散化+树状数组)
    poj 3321(树状数组)
  • 原文地址:https://www.cnblogs.com/zxqxwnngztxx/p/6720183.html
Copyright © 2011-2022 走看看