题目链接:
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;
}