FZU 2122 又见LKity
Posted 小小八
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FZU 2122 又见LKity相关的知识,希望对你有一定的参考价值。
题目链接:又见LKity
...真是不知道怎么被这个水题卡这么久的,开始用kmp,就是过不了,无脑dbug未果。换了一种kmp模板结果就过了。确实这个模板更好理解一些吧。
然后暴力0ms过的不知道什么鬼。
正解kmp一次求出每个字串的位置,代码:
AC版:
/* 已 AC */ #include <stdio.h> #include <string.h> #include <iostream> using namespace std; char s1[210], s2[210], s3[150010]; int next[210]; void getnext(char p[]) { memset(next, 0, sizeof(next)); int len = strlen(p); int i = 0; next[0] = -1; int k = -1; while(i<len) { if (k == -1 || p[i] == p[k] || p[i] + 32 == p[k] || p[i] == p[k] + 32) { i++; k++; next[i] = k; } else k = next[k]; } } void kmp(char s[], char p[]) { int lens = strlen(s); int lenp = strlen(p); int i = 0, j = 0; while(i<lens && j<lenp) { if (j == -1 || s[i] == p[j] || s[i] + 32 == p[j] || s[i] == p[j] + 32) { i++; j++; } else j = next[j]; if (j == lenp) { // 说明p[0]到p[len-1]已经匹配成功 s[i-lenp] ... s[i-1] 和 P[0] ... p[lenp-1] 匹配。 for (int k=i-lenp; k<i; ++k) { s[k] = ‘~‘; } j = next[j]; } } } int main() { while(~scanf("%[^\n]", s1)) { getchar(); scanf("%[^\n]", s2); getchar(); scanf("%[^\n]", s3); getchar(); int len1 = strlen(s1); int len2 = strlen(s2); int len3 = strlen(s3); getnext(s1); kmp(s3, s1); //cout << s1 << "===\n" << s2 << "===\n" << s3 << "===\n"; for (int i=0; i<len3; ++i) { if (s3[i] == ‘~‘) { printf("%s", s2); i += len1 - 1; } else printf("%c", s3[i]); } printf("\n"); } return 0; }
莫名WA版:
/* WA */ #include <stdio.h> #include <string.h> #include <iostream> #include <cmath> using namespace std; char s1[210], s2[210], s3[150010]; int next[210]; void getnext(char p[]) { memset(next, 0, sizeof(next)); int len = strlen(p+1); next[1] = 0; for (int k=0, q=2; q<=len; ++q) { while(k>0 && abs(p[k+1]-p[q]) != 32 && p[k+1] != p[q]) k = next[k]; if (p[k+1] == p[q] || abs(p[k+1]-p[q]) == 32 || k==0) k++; next[q] = k; } } bool check(char temp) { if (temp >= ‘A‘ && temp <= ‘Z‘) return true; if (temp >= ‘a‘ && temp <= ‘z‘) return true; return false; } void kmp(char T[], char P[]) { int lenp = strlen(P+1); int lent = strlen(T+1); getnext(P); for (int i=1, q=0; i<=lent; ++i) { while(q>0 && !(P[q+1] == T[i] || (check(T[i]) && abs(P[q+1]-T[i]) == 32))) q = next[q]; if (P[q+1] == T[i] || (check(T[i]) && abs(P[q+1]-T[i]) == 32)) q++; if (q == lenp) { for (int j=i-lenp+1; j<=i; ++j) T[j] = ‘~‘; q = next[q]; i = i + lenp - 1; } } } int main() { while(~scanf("%[^\n]", s1+1)) { getchar(); scanf("%[^\n]", s2+1); getchar(); scanf("%[^\n]", s3+1); getchar(); kmp(s3, s1); int len1 = strlen(s1+1); int len2 = strlen(s2+1); int len3 = strlen(s3+1); for (int i=1; i<=len3; ++i) { if (s3[i] == ‘~‘) { for (int j=1; j<=len2; ++j) { printf("%c", s2[j]); } i = i + len1 - 1; } else printf("%c", s3[i]); } printf("\n"); } return 0; }
暴力版:
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; char s1[210], s2[210], s3[210]; int main() { while(~scanf("%[^\n]", s1)) { getchar(); scanf("%[^\n]", s2); getchar(); scanf("%[^\n]", s3); getchar(); int len1 = strlen(s1); int len2 = strlen(s2); int len3 = strlen(s3); for (int i=0; i<len3; ++i) { bool ok= true; for (int j=0; j<len1; ++j) { if (s3[i+j] != s1[j] && s3[i+j] + 32 != s1[j] && s3[i+j] != s1[j] + 32) { ok = false; break; } } if (ok) { i += len1 - 1; printf("%s", s2); } else printf("%c", s3[i]); } printf("\n"); } return 0; }
希望不会再浪费这么多时间做无用功!
以上是关于FZU 2122 又见LKity的主要内容,如果未能解决你的问题,请参考以下文章
FZU 2122——又见LKity——————字符串匹配暴力
FZU 2122 ——又见LKity——————KMP字符串匹配