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 (2≤N≤100). 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("%[^\n]", s1); 23 int len = inf; 24 for(int i = 1; i < n; i++){ 25 getchar(); 26 scanf("%[^\n]", 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\n"); 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("\n"); 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("%[^\n]", 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\n"); 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("\n"); 93 } 94 95 return 0; 96 }