题目链接:
http://codeforces.com/contest/379/problem/D
题目大意:
给定一个长度为n的字符串s1和一个长度为m的字符串s2。
做k - 2次类似斐波那契的操作:sk = s(k-1) + s(k-2)。
已知sk中恰好含有k个"AC"子串,求是否存在符合条件的s1、s2
算法:
显然,除了s1和s2内部的"AC"以外,还有可能是在做连接操作的时候两字符串首位相接的拼成了"AC"。
通过简单的递推不难求出sk中包含多少个s1、s2,已经有多少种s1+s2,s2+s1,s2+s2的情况.,这个找规律也可以
那么要计算有多少个被拼成的"AC",我们只需枚举s1和s2的第一个字母是否是'C',最后一个字母是否是'A'
通过有多少种s1+s2,s2+s1,s2+s2的情况,可以算出有多少个"AC"是字符串首尾相接的时候拼成的
再枚举每个字符串内部有多少个“AC”,因为字符串很短,也很容易做到
这道题的算法可以说是不具备任何难度,但是貌似比赛的时候因为细节问题挂了不少人,所以在这里记录一下。
看这么简单的题写的这么长还真是无语哎。。
代码:
#include <cstdio> #include <iostream> #include <algorithm> #include <sstream> #include <cstdlib> #include <cstring> #include <string> #include <climits> #include <cmath> #include <queue> #include <vector> #include <stack> #include <set> #include <map> #define INF 0x3f3f3f3f #define eps 1e-8 using namespace std; long long fib[100][3][3]; int flg[3][3]; char a[200], b[200]; int main() { memset(fib, 0, sizeof(fib)); fib[1][1][0] = 1LL; fib[2][2][0] = 1LL; for(int i = 3; i <= 50; i ++) { for(int j = 1; j <= 2; j ++) { for(int k = 0; k <= 2; k ++) { fib[i][j][k] = fib[i - 1][j][k] + fib[i - 2][j][k]; } } if(i == 3) { fib[i][1][2] ++; } else if(i & 1) { fib[i][2][2] ++; } else { fib[i][2][1] ++; } } int k, n, m; long long x; scanf("%d %I64d %d %d", &k, &x, &n, &m); if(! x) { for(int i = 0; i < n; i ++) { putchar('A'); } puts(""); for(int i = 0; i < m; i ++) { putchar('A'); } puts(""); } else { bool flag = true; memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); for(flg[1][1] = 0; flg[1][1] < 2 && flag; flg[1][1] ++) { for(flg[1][2] = 0; flg[1][2] < 2 && flag; flg[1][2] ++) { for(flg[2][1] = 0; flg[2][1] < 2 && flag; flg[2][1] ++) { for(flg[2][2] = 0; flg[2][2] < 2 && flag; flg[2][2] ++) { int ln = n - flg[1][1] - flg[1][2]; int lm = m - flg[2][1] - flg[2][2]; for(int cot1 = 0; cot1 * 2 <= ln && flag; cot1 ++) { for(int cot2 = 0; cot2 * 2 <= lm && flag; cot2 ++) { long long tmp = cot1 * fib[k][1][0] + cot2 * fib[k][2][0]; for(int fi = 1; fi <= 2; fi ++) { for(int nd = 1; nd <= 2; nd ++) { if(flg[fi][1] && flg[nd][2]) { tmp += fib[k][fi][nd]; } } } if(tmp == x) { flag = false; int tot1 = 0, tot2 = 0; if(flg[1][1]) { a[n - 1] = 'A'; } if(flg[1][2]) { a[0] = 'C', tot1 = 1; } if(flg[2][1]) { b[m - 1] = 'A'; } if(flg[2][2]) { b[0] = 'C', tot2 = 1; } for(int i = 0; i < cot1; i ++) { a[i * 2 + tot1] = 'A'; a[i * 2 + tot1 + 1] = 'C'; } for(int i = 0; i < cot2; i ++) { b[i * 2 + tot2] = 'A'; b[i * 2 + tot2 + 1] = 'C'; } } } } } } } } if(flag) { puts("Happy new year!"); } else { for(int i = 0; i < n; i ++) { if(a[i]) { putchar(a[i]); } else { putchar('B'); } } puts(""); for(int i = 0; i < m; i ++) { if(b[i]) { putchar(b[i]); } else { putchar('B'); } } puts(""); } } return 0; }