Codeforces 379D - New Year Letter
原题地址:http://codeforces.com/contest/379/problem/D
题目大意:给出一种生成字符串的方法 s[k] = s[k - 2] + s[k - 1],其中加法意为将左右两个字符串直接相连,要求构造两个长度分别为n、m的字串s[1]、s[2],使得按照这种方法得出的s[k]中恰好含有 x 个 “AC”(意思大家都懂的……)如果无解,输出“Happy new year!”
数据范围:3 ≤ k ≤ 50; 0 ≤ x ≤ 109; 1 ≤ n, m ≤ 100
题目分析:
这道题算法很明确。
先将问题反过来思考:假设给定两个串s[1]、s[2],用题目中的方法生成s[k],求出s[k]含有几个“AC”,显然可以用动态规划解决
定义f[k]表示第k个串中含有“AC”的个数,Suf[k]为第 k 个串的结尾字母,Pre[k]为第k个串的开头字母,三个数组的1、2两位都是已知的
显然可以得到动态规划方程 f[k] = f[k - 2] + f[k - 1] + (Suf[k - 2] == 'A') && (Pre[k - 1] == 'C'); Suf[k] = Suf[k - 1]; Pre[k] = Pre[k - 2]
然后搞一搞就得到答案了。那么我们回归这道题,发现可以通过枚举f[1]、f[2]、Suf[1]、Suf[2]、Pre[1]、Pre[2]来DP计算所有可能的f[k],如果找到一组f[1]、f[2]、Suf[1]、Suf[2]、Pre[1]、Pre[2]使得f[k] == x,就按照它们构造两个字符串输出就好了
复杂度分析:每次枚举Pre[1]等等都是三种情况(是A、是C、不是A也不是C),一共枚举4轮,枚举f[1]时不可能超过二分之n,枚举f[2]时也同理,所以枚举的总复杂度是O(3 * 3 * (m / 2) * 3 * 3 * (n / 2))大约为202500,每次DP都是线性的所以复杂度是O(k)所以总复杂度可以约归为O(nmk)大概在10^7左右勉强不会超时。
剩下的就是细节了,这道题一大堆特殊情况需要判断(比如n , m <= 2啦什么的),详见代码~
//date 20140120
#include <cstdio>
#include <cstring> inline int min(int a, int b){return a < b ? a : b;}
inline int max(int a, int b){return a > b ? a : b;} int k, n, m;
long long x;
long long f[];
int suf[], pre[]; void dp(int w)
{
if(w <= )return;
if(f[w - ] == -)dp(w - );
if(f[w - ] == -)dp(w - );
f[w] = f[w - ] + f[w - ] + ((suf[w - ] == ) && (pre[w - ] == ));
suf[w] = suf[w - ]; pre[w] = pre[w - ];
} inline void output(int S1, int S2, int P1, int P2, int i, int j)
{
// printf("%d %d %d %d %d %d\n", S1, P1, i, S2, P2, j);
char ans1[], ans2[];
memset(ans1, , sizeof ans1);
memset(ans2, , sizeof ans2);
ans1[] = P1 + 'A' - ;
ans2[] = P2 + 'A' - ;
ans1[n] = S1 + 'A' - ;
ans2[m] = S2 + 'A' - ;
// printf("%s\n%s\n", ans1 + 1, ans2 + 1); int a1 = , a2 = ;
if(i > && ans1[] == 'A')
{
ans1[] = 'C';a1 = ;
for(int q = ; q < i; ++q){ans1[q * + ] = 'A'; ans1[q * + ] = 'C'; a1 = q * + ;}
for(int q = a1; q < n; ++q)ans1[q] = 'B';
}
else
{
a1 = ;
for(int q = ; q <= i; ++q){ans1[q * ] = 'A'; ans1[q * + ] = 'C'; a1 = q * + ;}
for(int q = a1; q < n; ++q)ans1[q] = 'B';
}
if(j > && ans2[] == 'A')
{
ans2[] = 'C'; a2 = ;
for(int q = ; q < j; ++q){ans2[q * + ] = 'A'; ans2[q * + ] = 'C'; a2 = q * + ;}
for(int q = a2; q < m; ++q)ans2[q] = 'B';
}
else
{
a2 = ;
for(int q = ; q <= j; ++q){ans2[q * ] = 'A'; ans2[q * + ] = 'C'; a2 = q * + ;}
for(int q = a2; q < m; ++q)ans2[q] = 'B';
}
printf("%s\n%s\n", ans1 + , ans2 + );
} int main()
{
// freopen("d.in", "r", stdin); scanf("%d%I64d%d%d", &k, &x, &n, &m); for(int P1 = ; P1 <= ; ++P1)
for(int S1 = ; S1 <= ; ++S1)
for(int P2 = ; P2 <= ; ++P2)
for(int S2 = ; S2 <= ; ++S2)
{
if(n == && S1 != P1)continue;
if(m == && S2 != P2)continue;
int uLim1 = , uLim2 = , dLim1 = , dLim2 = ;
uLim1 = max(n / - , ); if((n >= ) && ((S1 == && P1 == ) || ((n & ) && (S1 == || P1 == ))))++uLim1;
uLim2 = max(m / - , ); if((m >= ) && ((S2 == && P2 == ) || ((m & ) && (S2 == || P2 == ))))++uLim2;
if(n == && S1 == && P1 == )dLim1 = uLim1 = ;
if(m == && S2 == && P2 == )dLim2 = uLim2 = ;
// printf("%d %d %d %d\n", dLim1, uLim1, dLim2, uLim2);
for(int i = dLim1; i <= uLim1; ++i)
for(int j = dLim2; j <= uLim2; ++j)
{
memset(suf, , sizeof suf);
memset(pre, , sizeof pre);
suf[] = S1; suf[] = S2;
pre[] = P1; pre[] = P2;
memset(f, 0xFF, sizeof f);
f[] = i; f[] = j;
dp(k);
// printf("%d %d %d %d %d %d %d\n", P1, S1, P2, S2, i, j, f[k]);
if(f[k] == x){output(S1, S2, P1, P2, i, j); return ;}
}
} printf("Happy new year!\n");
return ;
}
小注:希望通过这道题能给我和大家带来更多的新年AC~
Codeforces 379D - New Year Letter的更多相关文章
- codeforces Good Bye 2013 379D New Year Letter
题目链接:http://codeforces.com/problemset/problem/379/D [题目大意] 告诉你初始字符串S1.S2的长度和递推次数k, 使用类似斐波纳契数列的字符串合并的 ...
- 【codeforces 379D】New Year Letter
[题目链接]:http://codeforces.com/contest/379/problem/D [题意] 让你构造出两个长度分别为n和m的字符串s[1]和s[2] 然后按照连接的规则,顺序连接s ...
- CodeForces 379D 暴力 枚举
D. New Year Letter time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Codeforces Round #284 (Div. 2)A B C 模拟 数学
A. Watching a movie time limit per test 1 second memory limit per test 256 megabytes input standard ...
- cf499B-Lecture 【map】
http://codeforces.com/problemset/problem/499/B B. Lecture You have a new professor of graph theo ...
- 物联网学生科协第三届H-star现场编程比赛
问题 A: 剪纸片 时间限制: 1 Sec 内存限制: 128 MB 题目描写叙述 这是一道简单的题目,假如你身边有一张纸.一把剪刀.在H-star的比赛现场,你会这么做: 1. 将这张纸剪成两片(平 ...
- Codeforces Round #116 (Div. 2, ACM-ICPC Rules) C. Letter 暴力
C. Letter Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/180/problem/C D ...
- Codeforces Beta Round #14 (Div. 2) A. Letter 水题
A. Letter 题目连接: http://www.codeforces.com/contest/14/problem/A Description A boy Bob likes to draw. ...
- CodeForces 379 D. New Year Letter
枚举开头结尾的字母,枚举ac的个数,总AC个数就是两个Fibonacci数列的和..... D. New Year Letter time limit per test 1 second memory ...
随机推荐
- 设置NODE_ENV=production
NodeJS - Express 4.0下设置环境变量NODE_ENV=production,并不是修改文件的配置信息,而是通过命令行来实现. 首先在命令行下进入项目的目录,然后先后执行如下命令: s ...
- OC面向对象封装
面向对象语言的三大特性:封装.继承.多态 封装:不暴露自己类的内部的属性,提高自己的数据的安全性:就像一个接线盒一样,内部结构看不到,只有外部的接口提供给我们使用,这样既安全又美观:在代码方面就是结构 ...
- WPF 多线程处理(1)
WPF 多线程处理(1) WPF 多线程处理(2) WPF 多线程处理(3) WPF 多线程处理(4) WPF 多线程处理(5) WPF 多线程处理(6) 废话不多说,先上图: 多线程处理数据后在th ...
- Module模式 - 深入了解Javascript
/* Modelu模式 优点:效率高,代码少,加载速度快,松耦合允许并行加载,提升下载速度 缺点:初始化时间久一点 */ //一.基础用法 var calculate = function (eq) ...
- mysql 错误- 磁盘空间不足,
mysql 磁盘空间不足错误 磁盘空间满了, 写不进去了. :: mysqld_safe Starting mysqld daemon with databases from /alidata/ser ...
- PE文件结构详解(四)PE导入表
PE文件结构详解(二)可执行文件头的最后展示了一个数组,PE文件结构详解(三)PE导出表中解释了其中第一项的格式,本篇文章来揭示这个数组中的第二项:IMAGE_DIRECTORY_ENTRY_IMPO ...
- 写一个函数,实现两个字符串的比较。即实现strcmp函数,s1=s2时返回0,s1!=s2时返回二者第一个不同字符的ASCII值。
#include<stdio.h> #include<stdlib.h> int main(){ setvbuf(stdout,NULL,_IONBF,); ],s2[]; i ...
- 【系统Configmachine.config与自己的应用程序的App.config/Web.Config配置节点重复】解决方法
自己的应用程序的App.config或Web.Config文件中与系统的C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Configmachine.co ...
- PHP流程控制的替代语法
准备做个wordpress的主题,结果看到了如下的语法: <div id="primary" class="content-area"><ma ...
- Unity3dBug - OnEnable
最近 项目 因为 使用 active 代替 instantiate机制,很多时候 OnEnable 代理 OnStart. 然后发现一个 奇怪的 问题 void Awake() { Debug.Log ...