题目描述

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: 我知道了,你知道了吗?【递归】的更多相关文章

  1. 2017校赛 问题 F: 懒人得多动脑

    题目描述 小D的家A和学校B都恰好在以点F为焦点的双曲线上,而小D每日所需的生活水源在一条平行该双曲线准线的直线上,设它的值为v.大家都知道,每天都是要喝水的,但是小D有点懒,他希望自己能在去上学或者 ...

  2. 北工大2017校赛 1101:要打车的FanZzz

    题目链接: http://bjutacm.openjudge.cn/lianxi/1101/ 思路: 二分 + 二分图最大匹配. 开始的时候我想直接用最小费用流模型,后来发现这样是错误的.因为这道题实 ...

  3. 广工2017校赛-F-- tmk找三角

    http://gdutcode.sinaapp.com/problem.php?cid=1056&pid=5 Description 有一棵树,树上有只tmk.他在这棵树上生活了很久,对他的构 ...

  4. 2017 校赛 问题 B: CZJ-Superman

    题目描述 “那是只鸟?那是飞机?那是——超人!” 程序员在看完<CZJ-Superman>之后,励志要成为一名“CZJ-Superman”,学会了两个特殊技能ZZZ和JJJ,足以成为一名“ ...

  5. 2017 校赛 问题 E: 神奇的序列

    题目描述        Aurora在南宁发现了一个神奇的序列,即对于该序列的任意相邻两数之和都不是三的倍数.现在给你一个长度为n的整数序列,让你判断是否能够通过重新排列序列里的数字使得该序列变成一个 ...

  6. 2017校赛 C: 不爱学习的小W【模拟】

    题目描述 “叮铃铃”上课了,同学们都及时到了教室坐到了座位上,教室里有n行m列的座位而且刚好坐满.既然是上课,那老师叫学生回答问题就是再正常不过的事了,同样地,教室里也就有爱学习和不爱学习的学生了,爱 ...

  7. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  8. SCNU省选校赛第二场B题题解

    今晚的校赛又告一段落啦,终于"开斋"了! AC了两题,还算是满意的,英语还是硬伤. 来看题目吧! B. Array time limit per test 2 seconds me ...

  9. 2014上半年acm总结(1)(入门+校赛)

    大一下学期才开始了acm,不得不说有一点迟,但是acm确实使我的生活充实了很多,,不至于像以前一样经常没事干=  = 上学期的颓废使我的c语言学的渣的一笔..靠考前突击才基本掌握了语法 寒假突然醒悟, ...

随机推荐

  1. [转载] 使用C/C++语言编写基于DSP程序的注意事项

    原文地址:『转』使用C/C++语言编写基于DSP程序的注意事项作者:skysmile   1.不影响执行速度的情况下,可以使用c或c/c++语言提供的函数库,也可以自己设计函数,这样更易于使用“裁缝师 ...

  2. 《DSP using MATLAB》Problem 7.31

    参照Example7.27,因为0.1π=2πf1   f1=0.05,0.9π=2πf2   f2=0.45 所以0.1π≤ω≤0.9π,0.05≤|H|≤0.45 代码: %% +++++++++ ...

  3. 跟我一起了解koa(二)

    koa中路由动态传值 1.路由 路由(Routing)是由一个 URI(或者叫路径)和一个特定的 HTTP 方法(GET.POST 等) 组成的,涉及到应用如何响应客户端对某个网站节点的访问. 通俗的 ...

  4. 系统io统计

      $ cat /proc/diskstats sda sda1 sda2 gg- gg- gg- 主号 次号 名称 成功读 合并读 扇区读 读时间   每一列的含义分别为: 第一列为 设备号 (nu ...

  5. laravel--request类获取传值

    request类获取传值 Request类的方法很多,常用的有如下几个: Request -> all() : 表示一次性获取所有的传值(包括get和post,但不能获取参数) Request ...

  6. 修改input标签输入样式

    去掉input自带的边框: border-style:none;修改input输入的文字样式: input{ font-size: 24px; color:#5d6494; } 修改input框中占位 ...

  7. python 产生二项分布图练习

  8. 内核、中断和网络 $ sysctl -a | grep ...$ cat /proc/interrupts$ cat /proc/net/ip_conntrack /* may take some time on busy servers */$ netstat$ ss -s

    你的中断请求是否是均衡地分配给CPU处理,还是会有某个CPU的核因为大量的网络中断请求或者RAID请求而过载了? SWAP交换的设置是什么?对于工作站来说swappinness 设为 60 就很好, ...

  9. git出现“The file will have its original line endings in your working directory”错误

    一.现象: git add *时出现如下现象: The file will have its original line endings in your working directory 解决: G ...

  10. token流程图