标签:UI color algo ever tchar tran nop sam line
#include<cstdio> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<cstring> #include<iostream> #include<map> #define MAXN 100009 #define INF 0x3f3f3f3f #define eps 1e-11 + 1e-12/2 typedef long long LL; using namespace std; /* 字符串匹配! 假设密码文为c1 c2 c3 ..... cn 那么 原文可以设为 f(c1) f(c2) f(c3) f(c4)...f(cn) f() 的关系给出了! 已知s[]是由一部分 密码文 一部分原文组成的 那么我们可以将截获的密码 c1 c2 c3 ... cn f(c1) f(c2) f(c3)...f(cn)进行一次变换 f(c1) f(c2) f(c3) ......然后找匹配的最长长度,用原串长度减去匹配长度就是密码长度,接下来就好做了! 注意:如果f(f(c1)) == f(c1)怎么办!? 特殊判断一下:如果s[]串和f(s[])串相等,寻求Next[l],匹配的最长前后缀长度,用l-Next[l]就是密码文的长度。 还要注意!密码文的长度至少是n/2! */ char s[MAXN], t[MAXN], m[27]; int Next[MAXN]; map<char, char> M; void kmp_pre(int l) { int j = 0, k = Next[0] = -1; while (j < l) { if (k == -1 || t[j] == t[k]) Next[++j] = ++k; else k = Next[k]; } } int KMP(int l) { kmp_pre(l); int i, j, ans; i = j = ans = 0; for (int i = 0; i < l; i++) { while (j > 0 && s[i] != t[j]) j = Next[j]; if (s[i] == t[j]) j++; /*if (j >= l) { return j - l; }*/ } return j; } int main() { int T; scanf("%d", &T); while (T--) { memset(t, ‘\0‘, sizeof(t)); M.clear(); getchar(); scanf("%s%s", m, s); int lm = strlen(m); for (int i = 0; i < lm; i++) M[m[i]] = ‘a‘ + i; int l = strlen(s); if (l == 1) { printf("%c%c\n", s[0], M[s[0]]); continue; } for (int i = 0; i < l; i++) t[i] = M[s[i]]; if (strcmp(s, t) == 0) { kmp_pre(l); int r = l - Next[l]; if (l % 2 == 0) r = max(l / 2, r); else r = max(l / 2 + 1, r); for (int i = 0; i < r; i++) printf("%c", s[i]); for (int i = 0; i <r; i++) printf("%c", M[s[i]]); printf("\n"); continue; } int k = KMP(l); for (int i = 0; i < l - k; i++) printf("%c", s[i]); for (int i = 0; i < l - k; i++) printf("%c", M[s[i]]); printf("\n"); } }
标签:UI color algo ever tchar tran nop sam line
原文地址:http://www.cnblogs.com/joeylee97/p/7287170.html