2017校赛 问题 D: 我知道了,你知道了吗?【递归】
题目描述
Alice和Bob走在去学校的路上,听到两个路人的对话:
路人甲:我知道了, 你知道了吗?
路人乙:我知道你知道了,你知道了吗?
路人甲:我知道你知道我知道了,你知道了吗?
路人乙:我知道你知道我知道你知道了,你知道了吗?
.........
他们便觉得十分有趣,觉得非常像两个人在玩字符串拼接的游戏,受此启发,Alice和Bob玩起了”类似”的拼接游戏:
Alice首先会选择四个字符串S1, A, B, C,之后Alice和Bob轮流拼接出第2,第3,第4....第n个字符串,对于第i个字符串Si (i > 1), 它的拼接规则是Si = A + Si-1 + B + Si-1 + C,其中符号“+”是字符串连接的意思,举个例子:
Alice先选择了S1 = “ab”, A = “CD”, B = “EF”, C = “GH”,接下来的操作是:
Bob 拼接出 S2 = “CDabEFabGH”
Alice拼接出 S3 = “CDCDabEFabGHEFCDabEFabGHGH”
...........
走在路上的你恰巧看到了Alice和Bob玩游戏的整个过程,Alice就问你,在他们拼出的第n个字符串中的第k个字符是什么?Alice和Bob都已经知道了,你知道了吗?假设无论多长的字符串Alice和Bob都能拼接出来。
注意引号是定界符,不属于字符串。
输入
输入包括多组数据(数据组数总共不超过50)。
每组第一行有四个字符串,分别是S1, A, B, C(长度都<=100),字符串只包含小写英文字母和大写英文字母.
第二行一个整数q(1 <= q <= 50),表示Alice询问的次数。
接下来有q行, 每组两个整数n(1 <= n <= 1000)和k(1 <= k <= 100000000),分别代表Alice和Bob拼接出的第n个字符串以及第n个字符串中的第k个字符。
输出
对于每个n和k,输出对应的Alice和Bob拼接出的第n个字符串中第k个字符。如果第n个字符串中第k个字符不存在输出’*’。每个答案独占一行。
样例输入
ab CD EF GH
5
1 1
1 2
1 3
2 10
2 11
样例输出
a
b
*
H
* 越补题越崩溃,点背加经验少。。。。
记录下个人思路:
显然第n个字符串是个递推式:
那么我求第n个字符串的第k个字符只需要判断k的范围即可,如果k<=len(A),就在A中找相应位置,如果k>len(A)&&k<=len(Sn-1)就递归到Sn-1,在Sn-1中找第k-len(A)个位置,以此类推。。。。
所以这道题刚开始我这样写:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int ls,la,lb,lc;
int s[];
char s1[],A[],B[],C[]; void solve(int n,int k)
{
if(n==){
printf("%c\n",s1[k-]);
return;
}
if(k<=la){
printf("%c\n",A[k-]);
return;
}else if(k>la+s[n-]&&k<=la+s[n-]+lb){
printf("%c\n",B[k-la-s[n-]-]);
return;
}else if(k>la+lb+*s[n-]&&k<=la+lb+lc+*s[n-]){
printf("%c\n",C[k-la-lb-*s[n-]-]);
return;
}else if(k>la&&k<=la+s[n-]){
solve(n-,k-la);
return;
}else {
solve(n-,k-la-lb-s[n-]);
return;
}
} int main()
{
while(scanf("%s%s%s%s",s1,A,B,C)==)
{
memset(s,,sizeof(s));
ls=strlen(s1);la=strlen(A);
lb=strlen(B);lc=strlen(C);
s[]=ls;
for(int i=;i<=;i++){
s[i]=s[i-]*+la+lb+lc;
}
int q,n,k;
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&n,&k);
if(k>s[n]) printf("*\n");
else{
solve(n,k);
}
}
}
return ;
}
错误写法
显然,运行错误(段错误),就是超数组边界了。后来再想想,len(Sn)=2*len(Sn-1)+len(A)+len(B)+len(C)==>len(Sn)=2^(n-1)len(s1)+(4*n-5)*[len(A)+len(B)+len(C)](大概推了一下,可能有错误)。可以看出,字符串的长度是呈指数形式增长的,自然存到n=30数就已经很大很大了,又有k<=10^8,那么也就是说即便S1,A,B,C长度均为1,n==28时已经大于这个数了(2^27约为134217728)。所以当n>=28时长度已经足够达到k的最大值。所以我只存到n=28,当n>28时根据递推式推到n<=28的范围内再用上面的做法解决。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
ll ls,la,lb,lc;
ll s[];
char s1[],A[],B[],C[]; void solve(int n,int k)
{
if(n==){
printf("%c\n",s1[k-]);
return;
}
if(k<=la){
printf("%c\n",A[k-]);
return;
}else if(k>la+s[n-]&&k<=la+s[n-]+lb){
printf("%c\n",B[k-la-s[n-]-]);
return;
}else if(k>la+lb+*s[n-]&&k<=la+lb+lc+*s[n-]){
printf("%c\n",C[k-la-lb-*s[n-]-]);
return;
}else if(k>la&&k<=la+s[n-]){
solve(n-,k-la);
return;
}else {
solve(n-,k-la-lb-s[n-]);
return;
}
} int main()
{
while(scanf("%s%s%s%s",s1,A,B,C)==)
{
memset(s,,sizeof(s));
ls=strlen(s1);la=strlen(A);
lb=strlen(B);lc=strlen(C);
s[]=ls;
for(int i=;i<=;i++){
s[i]=s[i-]*+la+lb+lc;
}
int q,n,k;
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&n,&k);
int pos=;
for(int i=;i<=;i++)
if(s[i]>=k){
pos=i;break;
}
if(pos>n) printf("*\n");
else if(n<=){
solve(n,k);
}else {
int t=la*(n-);
if(t>=k){
int r=k%la;
printf("%c\n",A[r]);
}else{
solve(,k-t);
}
}
}
}
return ;
}
2017校赛 问题 D: 我知道了,你知道了吗?【递归】的更多相关文章
- 2017校赛 问题 F: 懒人得多动脑
题目描述 小D的家A和学校B都恰好在以点F为焦点的双曲线上,而小D每日所需的生活水源在一条平行该双曲线准线的直线上,设它的值为v.大家都知道,每天都是要喝水的,但是小D有点懒,他希望自己能在去上学或者 ...
- 北工大2017校赛 1101:要打车的FanZzz
题目链接: http://bjutacm.openjudge.cn/lianxi/1101/ 思路: 二分 + 二分图最大匹配. 开始的时候我想直接用最小费用流模型,后来发现这样是错误的.因为这道题实 ...
- 广工2017校赛-F-- tmk找三角
http://gdutcode.sinaapp.com/problem.php?cid=1056&pid=5 Description 有一棵树,树上有只tmk.他在这棵树上生活了很久,对他的构 ...
- 2017 校赛 问题 B: CZJ-Superman
题目描述 “那是只鸟?那是飞机?那是——超人!” 程序员在看完<CZJ-Superman>之后,励志要成为一名“CZJ-Superman”,学会了两个特殊技能ZZZ和JJJ,足以成为一名“ ...
- 2017 校赛 问题 E: 神奇的序列
题目描述 Aurora在南宁发现了一个神奇的序列,即对于该序列的任意相邻两数之和都不是三的倍数.现在给你一个长度为n的整数序列,让你判断是否能够通过重新排列序列里的数字使得该序列变成一个 ...
- 2017校赛 C: 不爱学习的小W【模拟】
题目描述 “叮铃铃”上课了,同学们都及时到了教室坐到了座位上,教室里有n行m列的座位而且刚好坐满.既然是上课,那老师叫学生回答问题就是再正常不过的事了,同样地,教室里也就有爱学习和不爱学习的学生了,爱 ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- SCNU省选校赛第二场B题题解
今晚的校赛又告一段落啦,终于"开斋"了! AC了两题,还算是满意的,英语还是硬伤. 来看题目吧! B. Array time limit per test 2 seconds me ...
- 2014上半年acm总结(1)(入门+校赛)
大一下学期才开始了acm,不得不说有一点迟,但是acm确实使我的生活充实了很多,,不至于像以前一样经常没事干= = 上学期的颓废使我的c语言学的渣的一笔..靠考前突击才基本掌握了语法 寒假突然醒悟, ...
随机推荐
- bootstrab table+表格 select可编辑完整实例
先看下效果图: ============================================================================================ ...
- Win3.2有人用过么
老牌子的操作系统. 了,有人用过么,我还在用,感觉挺不错的,哈哈哈哈哈. 1.0那一代,画面粗糙,几乎不能算GUI操作系统. 2.0,画面较1.0一代明显改善,可惜的是,手头没货. 3.0 ...
- 跟我一起了解koa(一)
安装koa2 1.初始化package.json npm init 2.新建app.js,并且安装koa cnpm install --save koa //app.js const koa = re ...
- 配置android studio环境-Hello world
运行hello world demo 运行D:\Program Files\Android\Android Studio\bin 选择创建一个项目 出现一系列的选择 如果没有出现下列问题,直接跳过 备 ...
- CSS中position和header和overflow和background
<!DOCTYPE html> <!--CSS中position属性--> <html lang="en"> <head> < ...
- LUOGU P3111 [USACO14DEC]牛慢跑Cow Jog_Sliver
传送门 解题思路 比较简单的一道思路题,首先假设他们没有前面牛的限制,算出每只牛最远能跑多远.然后按照初位置从大到小扫一遍,如果末位置大于等于前面的牛,那么就说明这两头牛连一块了. 代码 #inclu ...
- meta标签中设置apple-itunes-app的意义
告诉iphone的safari浏览器:这个网站对应的是哪个app <meta name="apple-itunes-app" content="app-id=589 ...
- bootstrap--响应式框架页面环境配置
那就目录结构 页面环境代码: <!DOCTYPE html> <html lang="zh-CN"> <head> <!--默认编码--& ...
- 锋利的JQuery学习之JQuery中的事件
一.加载DOM 在页面加载完毕之后,浏览器会通过javascript为dom元素添加事件,在常规的javascript中使用window.onload方法,而在jQuery中使用的是$(documen ...
- Redis数据库在ubuntu16.04下的安装
1.安装 sudo apt-get install redis-server 2.启动 sudo service redis-server start 3.查看 ps aux|grep redis 4 ...