HDU4300 Clairewd’s message

雪姐无敌~

 

这题传说是一个扩展KMP的应用,不过我不会exKMP,只好先用KMP乱搞一下了。


KMP我TMD也不会啊。。。这题就当加深理解了。。

 

我们将原串称为MIA,将解密后的串称为STR

我们要找到的的是MIA的后辍与STR的前辍的最长的交。

 

解题的方法就是以MIA为母串,以STR为模式串,做一次KMP匹配。从而求得当母串完全匹配之后,模式串的匹配位置。

 

如M:abcdab T:abcdab (样例,没有加密)

最后的匹配位置就是ab < ...

所以M的前4个是加密串,后4个可以由前4个解密得到。

 

但是,有特殊情况是abababa这样的。

匹配位置是len,而题目中给出的信息是M[0...n-1]+S[0...m]   (0<=m<len)

所以我们所要的结果就是next[ptr]。

再加上要求最短的信息串,则如果ptr>len/2,则ptr=next[ptr],这样就可以得到最后的结果。

 

学艺不精,语文不好,说错了不怪我。大家参考着看呗~~

 

View Code
 1 #include <cstdio>

 2 #include <cstdlib>

 3 #include <cstring>

 4 #include <algorithm>

 5 #include <iostream>

 6 #include <vector>

 7 #include <string>

 8 #include <bitset>

 9 

10 using namespace std;

11 

12 #define print(x) cout<<x<<endl

13 #define input(x) cin>>x

14 

15 const int SIZE=100000;

16 

17 int next[SIZE+5];

18 char conv[32],anti[32];

19 char str[SIZE+5],mia[SIZE+5];

20 int len;

21 

22 void kmp_get_next()

23 {

24     next[0]=-1;

25     for(int i=0,j=-1;i<len;i++,j++,next[i]=j)

26     {

27         while(j>=0 and str[i]!=str[j]) j=next[j];

28     }

29 }

30 

31 char decode(char x)

32 {

33     return conv[x-'a'];

34 }

35 

36 void make_anti()

37 {

38     for(int i=0;conv[i];i++)

39     {

40         anti[conv[i]-'a']='a'+i;

41     }

42 }

43 

44 char encode(char x)

45 {

46     return anti[x-'a'];

47 }

48 

49 int slove()

50 {

51     int i,j;

52     i=j=0;

53     while(i<len and j<len)

54     {

55         if(j==-1 or mia[i]==str[j])

56         {

57             i++;j++;

58         }

59         else

60         {

61             j=next[j];

62         }

63     }

64     while(j>len/2) j=next[j];

65     return j;

66 }

67 

68 int main()

69 {

70     int T;

71     input(T);

72     while(T--)

73     {

74         memset(mia,0,sizeof(mia));

75         memset(str,0,sizeof(str));

76         memset(next,0,sizeof(next));

77         scanf("%s",conv);

78         scanf("%s",str);

79         len=strlen(str);

80         for(int i=0;str[i];i++)

81         {

82             mia[i]=decode(str[i]);

83         }

84         make_anti();

85         kmp_get_next();

86         int k=slove();

87         for(int i=0;mia[i+k];i++)

88         {

89             printf("%c",str[i]);

90         }

91         for(int i=0;mia[i+k];i++)

92         {

93             printf("%c",encode(str[i]));

94         }

95         puts("");

96     }

97     return 0;

98 }

你可能感兴趣的:(message)