CF 379D: New Year Letter

来源:互联网 发布:java有哪些集合类 编辑:程序博客网 时间:2024/05/29 12:16

题目链接:

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-8using 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;}

0 0
原创粉丝点击