以下两份代码采用了hzq(这里)的解题思路。即在输入的a、b、c三个串中,如果c串有连续出现的字符,那么这些字符必定也在a或/和b中连续存在。基于这一思路,能够快速的处理tttttt tttttt tttttttttttt这样的输入。
代码一:递归+连续字符判断。
其中45~55的代码写得很漂亮。
/* * 作者:hzq * 修改前代码id:73251 * 修改者:lance */ #include <stdio.h> #include <string.h> int zipper(char *ch1, char *ch2, char *ch3) { int k, m, n; if (!*ch3) return 1; k = 1; while(*ch3 == *(ch3 + k)) k++; if (k > 2) { m = 0; while(*(ch2 + m) == *ch3) m++; n = 0; while(*(ch1 + n) == *ch3) n++; //最多只能从ch1或ch2中提取k个相同字符到ch3中 m = k < m ? k : m; n = k < n ? k : n; if (*(ch2 + m) == *(ch3 + k)) { ch1 += k - m; ch2 += m -1; ch3 += k -1; } else if (*(ch1 + n) == *(ch3 + k)) { ch1 += n -1; ch2 += k - n; ch3 += k -1; } else if (m+n <= k+1) return 0; } if ((ch1[0] == ch3[0]) || (ch2[0] == ch3[0])) { int i = 0; if (ch1[0] == ch3[0]) i = zipper(ch1+1, ch2, ch3+1); if (!i && ch2[0] == ch3[0]) i = zipper(ch1, ch2+1, ch3+1); return i; } else return 0; } int main() { //freopen("1324.in", "r", stdin); //freopen("1324.out", "w", stdout); char str1[460], str2[460]; char str3[910]; int d, n; scanf("%d\n", &n); for (d = 1; d <= n; d++) { scanf("%s%s%s", str1, str2, str3); if ((strlen(str1) + strlen(str2)) != strlen(str3)) { printf("Data set %d: no\n", d); continue; } if (zipper(str1, str2, str3)) printf("Data set %d: yes\n", d); else printf("Data set %d: no\n", d); } return 0; }
代码二:递归+循环+连续字符判断。
通过循环减少递归层次,避免数据过大时堆栈溢出。
/* *作者:lance */ #include <stdio.h> #include <string.h> int zipper(char *a, char *b, char *c) { while (1) { int k, m, n; if (*c == 0) return 1; k = 1; while (*c == *(c + k)) k++; if (k == 1) { if (*a == *b) { if (*c == *a) return zipper(a+1, b, c+1) || zipper(a, b+1, c+1); else return 0; } if (*c == *a) { a++, c++; continue; } else if (*c == *b) { b++, c++; continue; } else return 0; } //k!= 1的情况下,执行以下动作; m = 0; while (a[m] == *c) m++; n = 0; while (b[n] == *c) n++; //m+n 与 k的三种关系 if (m+n < k) return 0; if (m+n == k) { a += m, b += n, c += k; continue; } //k != 1 且 m+n > k的情况下,执行以下动作; m = k < m ? k : m; n = k < n ? k : n; return zipper(a+m, b+k-m, c+k) || zipper(a+k-n, b+n, c+k); } } int main() { //freopen("1324.in", "r", stdin); //freopen("1324.out", "w", stdout); char str1[460], str2[460]; char str3[910]; int d, n; scanf("%d\n", &n); for (d = 1; d <= n; d++) { scanf("%s%s%s", str1, str2, str3); if ((strlen(str1) + strlen(str2)) != strlen(str3)) { printf("Data set %d: no\n", d); continue; } if (zipper(str1, str2, str3)) printf("Data set %d: yes\n", d); else printf("Data set %d: no\n", d); } return 0; }