PAT甲1077 Kuchiguse字符串暴力Hash二分

Posted wyboooo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT甲1077 Kuchiguse字符串暴力Hash二分相关的知识,希望对你有一定的参考价值。

1077 Kuchiguse (20 分)

The Japanese language is notorious for its sentence ending particles. Personal preference of such particles can be considered as a reflection of the speaker‘s personality. Such a preference is called "Kuchiguse" and is often exaggerated artistically in Anime and Manga. For example, the artificial sentence ending particle "nyan~" is often used as a stereotype for characters with a cat-like personality:

  • Itai nyan~ (It hurts, nyan~)

  • Ninjin wa iyada nyan~ (I hate carrots, nyan~)

Now given a few lines spoken by the same character, can you find her Kuchiguse?

Input Specification:

Each input file contains one test case. For each case, the first line is an integer N (2N100). Following are N file lines of 0~256 (inclusive) characters in length, each representing a character‘s spoken line. The spoken lines are case sensitive.

Output Specification:

For each test case, print in one line the kuchiguse of the character, i.e., the longest common suffix of all N lines. If there is no such suffix, write nai.

Sample Input 1:

3
Itai nyan~
Ninjin wa iyadanyan~
uhhh nyan~

Sample Output 1:

nyan~

Sample Input 2:

3
Itai!
Ninjinnwaiyada T_T
T_T

Sample Output 2:

nai

 

题意:

给n个串求所有串的最长公共后缀。

思路:

觉得自己就是一个傻逼....

看到题目想到的直接是Hash+二分,敲完了WA了去看别人写的发现直接暴力两两找就行了,因为LCS长度是非递增的。

交完了暴力突然明白HashWA了是因为题目的意思是区分大小写,我以为那句话的意思是不区分大小写,还把大写转成了小写。

想太多。

 

 1 #include <iostream>
 2 #include <set>
 3 #include <cmath>
 4 #include <stdio.h>
 5 #include <cstring>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <queue>
 9 #include <map>
10 using namespace std;
11 typedef long long LL;
12 #define inf 0x7f7f7f7f
13 
14 const int maxn = 105;
15 int n;
16 char s1[300], s2[300];
17 
18 int main()
19 {
20     scanf("%d", &n);
21     getchar();
22     scanf("%[^
]", s1);
23     int len = inf;
24     for(int i = 1; i < n; i++){
25         getchar();
26         scanf("%[^
]", s2);
27         int k1 = strlen(s1) - 1, k2 = strlen(s2) - 1;
28         if(k1 > k2){
29             swap(s1, s2);
30             swap(k1, k2);
31         }
32         while(k1 >= 0 && s1[k1] == s2[k2]){
33             k1--;k2--;
34         }
35         //cout<<k1<<endl;
36         if(strlen(s1) - k1 - 1 < len){
37             len = strlen(s1) - k1 - 1;
38         }
39         //len = min(len, strlen(s1) - k1);
40     }
41     //cout<<len<<endl;
42     if(!len){
43         printf("nai
");
44     }
45     else{
46         int l = strlen(s1) - 1;
47         for(int i = l - len + 1; i <= l; i++){
48             printf("%c", s1[i]);
49         }
50         printf("
");
51     }
52     return 0;
53 }

 

Hash + 二分

 1 #include <iostream>
 2 #include <set>
 3 #include <cmath>
 4 #include <stdio.h>
 5 #include <cstring>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <queue>
 9 #include <map>
10 using namespace std;
11 typedef long long LL;
12 #define inf 0x7f7f7f7f
13 
14 const int maxn = 105;
15 int n, len[maxn];
16 char s[maxn][300];
17 unsigned long long h[maxn][300], p[300];
18 
19 unsigned long long get_hash(int i, int j, int id)
20 {
21     return h[id][j] - h[id][i - 1] * p[j - i + 1];
22 }
23 
24 bool check(int mid)
25 {
26     unsigned long long x = get_hash(len[1] - mid + 1, len[1], 1);
27     //cout<<x<<endl;
28     for(int i = 2; i <= n; i++){
29         //cout<<get_hash(len[i] - mid + 1, len[i], i)<<endl;
30         if(x != get_hash(len[i] - mid + 1, len[i], i)){
31             return false;
32         }
33     }
34     return true;
35 }
36 
37 int main()
38 {
39     scanf("%d", &n);
40     p[0] = 1;
41     for(int i = 1; i < 300; i++){
42         p[i] = p[i - 1] * 13331;
43     }
44     int minlen = inf;
45     for(int i = 1; i <= n; i++){
46         getchar();
47         scanf("%[^
]", s[i] + 1);
48         //printf("%s", s[i] + 1);
49         len[i] = strlen(s[i] + 1);
50         minlen = min(minlen, len[i]);
51         h[i][0] = 0;
52         for(int j = 1; j <= len[i]; j++){
53             /*if(s[i][j] >= ‘A‘ && s[i][j] <= ‘Z‘){
54                 s[i][j] = s[i][j] - ‘A‘ + ‘a‘;
55             }*/
56             h[i][j] = h[i][j - 1] * 13331 + (int)s[i][j];
57         }
58     }
59 
60     //cout<<minlen<<endl;
61     /*for(int i = 1; i <= n; i++){
62         cout<<len[i]<<endl;
63     }*/
64     int st = 0, ed = minlen, ans = -1;
65     while(st <= ed){
66         int mid = (st + ed) / 2;
67         //cout<<mid<<endl;
68         if(check(mid)){
69             st = mid + 1;
70             ans = mid;
71         }
72         else{
73             ed = mid - 1;
74         }
75     }
76 
77     //cout<<ans<<endl;
78     if(ans < 1){
79         printf("nai
");
80     }
81     else{
82         bool flag = true;
83         for(int j = len[1] - ans + 1; j <= len[1]; j++){
84             if(flag && s[1][j] ==  ){
85                 continue;
86             }
87             if(flag && s[1][j] !=  ){
88                 flag = false;
89             }
90             printf("%c", s[1][j]);
91         }
92         printf("
");
93     }
94 
95     return 0;
96 }

 

以上是关于PAT甲1077 Kuchiguse字符串暴力Hash二分的主要内容,如果未能解决你的问题,请参考以下文章

1077. Kuchiguse (20)字符串处理——PAT (Advanced Level) Practise

PAT 1077 Kuchiguse

pat 1077 Kuchiguse(20 分) (字典树)

PAT1077. Kuchiguse (20)

PAT 1077 Kuchiguse (20)

[PAT] 1077 Kuchiguse (20 分)Java