zoukankan      html  css  js  c++  java
  • HDU 4300 Clairewd’s message(扩展kmp)

    http://acm.hdu.edu.cn/showproblem.php?pid=4300

    题意:
    给出两个字符串,第一个字符串是加密表,是用来将明文转化成密文的。

    第二个字符串是密文+明文,而且密文是完整的,但是明文不一定完整,现在要根据密文和加密表把所有明文表示出来,要求整个字符串长度最小。

    思路:

    看懂题意之后就比较好做了,原串的明文是后缀,现将原串根据加密表全部转化成明文,那么此时前缀就是明文,如果药整个字符串长度最小,那么确定的明文当然是越多越好了,计算一下最长公共前缀。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<map>
     5 using namespace std;
     6 const int maxn = 1000000+5;
     7 
     8 char s1[maxn],s2[maxn], p[30];
     9 int nxt[maxn],extend[maxn];
    10 
    11 map<char,char> mp;
    12 
    13 
    14 void preekmp(char x[], int m)
    15 {
    16     nxt[0] = m;
    17     int j = 0;
    18     while(j+1 <m && x[j] == x[j+1])  j++;
    19     nxt[1] = j;
    20     int k = 1;
    21     for(int i=2;i<m;i++)
    22     {
    23         int p = nxt[k]+k-1;
    24         int L = nxt[i-k];
    25         if(i+L<p+1)  nxt[i] = L;
    26         else
    27         {
    28             j = max(0,p-i+1);
    29             while(i+j<m && x[i+j]==x[j])  j++;
    30             nxt[i] = j;
    31             k = i;
    32         }
    33     }
    34     return;
    35 }
    36 
    37 void ekmp(char x[],int m,char y[],int n)
    38 {
    39     preekmp(x,m);
    40     int j = 0;
    41     while(j<n && j<m && x[j] == y[j]) j++;
    42     extend[0] = j;
    43     int k = 0;
    44     for(int i=1;i<n;i++)
    45     {
    46         int p = extend[k]+k-1;
    47         int L = nxt[i-k];
    48         if(i+L<p+1)  extend[i]=L;
    49         else
    50         {
    51             j = max(0,p-i+1);
    52             while(i+j<n && j<m && y[i+j]==x[j])  j++;
    53             extend[i] = j;
    54             k = i;
    55         }
    56     }
    57     return;
    58 }
    59 
    60 int main()
    61 {
    62     //freopen("in.txt","r",stdin);
    63     int T;
    64     scanf("%d",&T);
    65     while(T--)
    66     {
    67         mp.clear();
    68         scanf("%s%s",p,s1);
    69         int n = strlen(s1);
    70         for(int i=0;p[i];i++)  mp[p[i]]='a'+i;
    71         memset(s2,0,sizeof(s2));
    72         for(int i=0;i<n;i++)  s2[i] = mp[s1[i]];
    73         ekmp(s2,n,s1,n);
    74         int ans = n;
    75         for(int i=0;i<n;i++)
    76         {
    77             if(i+extend[i]>=n && i>=extend[i])
    78             {
    79                 ans = i;
    80                 break;
    81             }
    82         }
    83         for(int i=0;i<ans;i++)  printf("%c",s1[i]);
    84         for(int i=0;i<ans;i++)  printf("%c",mp[s1[i]]);
    85         printf("
    ");
    86     }
    87     return 0;
    88 }
  • 相关阅读:
    exploded archive 和packaged archive 区别
    MyEclipse6.5使用设置技巧及快捷键
    本机上设置域名解析
    Cookie的生命周期问题
    简单的函数柯里化
    cookie操作
    自定义事件
    解耦应用逻辑/事件处理程序
    dragdrop + 自定义事件
    在窃取函数中用作用域安全的构造函数
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7853507.html
Copyright © 2011-2022 走看看