题目描述

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)个位置,以此类推。。。。

所以这道题刚开始我这样写:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 int ls,la,lb,lc;
 8 int s[1006];
 9 char s1[105],A[105],B[105],C[105];
10
11 void solve(int n,int k)
12 {
13     if(n==1){
14         printf("%c\n",s1[k-1]);
15         return;
16     }
17     if(k<=la){
18         printf("%c\n",A[k-1]);
19         return;
20     }else if(k>la+s[n-1]&&k<=la+s[n-1]+lb){
21         printf("%c\n",B[k-la-s[n-1]-1]);
22         return;
23     }else if(k>la+lb+2*s[n-1]&&k<=la+lb+lc+2*s[n-1]){
24         printf("%c\n",C[k-la-lb-2*s[n-1]-1]);
25         return;
26     }else if(k>la&&k<=la+s[n-1]){
27         solve(n-1,k-la);
28         return;
29     }else {
30         solve(n-1,k-la-lb-s[n-1]);
31         return;
32     }
33 }
34
35 int main()
36 {
37     while(scanf("%s%s%s%s",s1,A,B,C)==4)
38     {
39         memset(s,0,sizeof(s));
40         ls=strlen(s1);la=strlen(A);
41         lb=strlen(B);lc=strlen(C);
42         s[1]=ls;
43         for(int i=2;i<=1001;i++){
44             s[i]=s[i-1]*2+la+lb+lc;
45         }
46         int q,n,k;
47         scanf("%d",&q);
48         while(q--)
49         {
50             scanf("%d%d",&n,&k);
51             if(k>s[n]) printf("*\n");
52             else{
53                 solve(n,k);
54             }
55         }
56     }
57     return 0;
58 }
59  

错误写法

显然,运行错误(段错误),就是超数组边界了。后来再想想,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的范围内再用上面的做法解决。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 typedef long long ll;
 8 ll ls,la,lb,lc;
 9 ll s[31];
10 char s1[105],A[105],B[105],C[105];
11
12 void solve(int n,int k)
13 {
14     if(n==1){
15         printf("%c\n",s1[k-1]);
16         return;
17     }
18     if(k<=la){
19         printf("%c\n",A[k-1]);
20         return;
21     }else if(k>la+s[n-1]&&k<=la+s[n-1]+lb){
22         printf("%c\n",B[k-la-s[n-1]-1]);
23         return;
24     }else if(k>la+lb+2*s[n-1]&&k<=la+lb+lc+2*s[n-1]){
25         printf("%c\n",C[k-la-lb-2*s[n-1]-1]);
26         return;
27     }else if(k>la&&k<=la+s[n-1]){
28         solve(n-1,k-la);
29         return;
30     }else {
31         solve(n-1,k-la-lb-s[n-1]);
32         return;
33     }
34 }
35
36 int main()
37 {
38     while(scanf("%s%s%s%s",s1,A,B,C)==4)
39     {
40         memset(s,0,sizeof(s));
41         ls=strlen(s1);la=strlen(A);
42         lb=strlen(B);lc=strlen(C);
43         s[1]=ls;
44         for(int i=2;i<=29;i++){
45             s[i]=s[i-1]*2+la+lb+lc;
46         }
47         int q,n,k;
48         scanf("%d",&q);
49         while(q--)
50         {
51             scanf("%d%d",&n,&k);
52             int pos=1;
53             for(int i=1;i<=28;i++)
54             if(s[i]>=k){
55                 pos=i;break;
56             }
57             if(pos>n) printf("*\n");
58             else if(n<=28){
59                 solve(n,k);
60             }else {
61                 int t=la*(n-28);
62                 if(t>=k){
63                     int r=k%la;
64                     printf("%c\n",A[r]);
65                 }else{
66                     solve(28,k-t);
67                 }
68             }
69         }
70     }
71     return 0;
72 }

转载于:https://www.cnblogs.com/zxhyxiao/p/8073758.html

2017校赛 问题 D: 我知道了,你知道了吗?【递归】相关推荐

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

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

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

    题目描述 "那是只鸟?那是飞机?那是--超人!" 程序员在看完<CZJ-Superman>之后,励志要成为一名"CZJ-Superman",学会了两 ...

  3. HAUT 1262 魔法宝石(spfa)(河南工业大学2017校赛)

    魔法宝石 题目描述 小s想要创造n种魔法宝石.小s可以用ai的魔力值创造一棵第i种魔法宝石,或是使用两个宝石合成另一种宝石(不消耗魔力值).请你帮小s算出合成某种宝石的所需的最小花费. 输入 第一行为 ...

  4. HAUT 1261 地狱飞龙(数值积分)(河南工业大学2017校赛)

    地狱飞龙 题目描述 最近clover迷上了皇室战争,他抽到了一种地狱飞龙,很开心.假设地域飞龙会对距离为d的敌人每秒造成k/d2伤害.假设地域飞龙位于坐标轴原点,以每秒v1的速度向y轴正方向移动,敌人 ...

  5. “师创杯”山东理工大学第九届ACM程序设计竞赛 正式赛 F.校赛~校赛~【思维+规律题】

    校赛~校赛~ Time Limit: 1000MS  Memory Limit: 65536KB Submit  Statistic Problem Description SDUT 的校赛是从 20 ...

  6. 一个彻彻底底的水军的ACM校赛感悟~~~

    2017年4月23日刚刚结束了ACM校赛.作为一名不是ACM队的水军来说,抱着必突突突的决心,参加了这次的比赛.经过五个小时的激烈角逐,我们队伍还参加了一场和我们没有什么关系的颁奖典礼. 我是一个编程 ...

  7. [置顶]2010年东北大学ACM程序设计竞赛冬季校赛题解

    8题只做出4题比较easy的题,而且做得挺麻烦,看来还要多练练. AC的题如下 NEUOJ  1112 I Love Apple Description So many people love app ...

  8. 关于安徽赛区推广校赛的实施办法

    关于安徽赛区 推广校赛的实施办法 全国组委会:   安徽赛区作为第一个省级赛区自2010年举办至今,受到安徽省教育厅和安徽各高校高度认可,是安徽省教育厅重点支持的大学生学科和技能竞赛A类赛事.但安徽赛 ...

  9. 第18届浙江大学校赛 Mergeable Stack

    The 18th Zhejiang University Programming Contest Sponsored by TuSimple 第18届浙江大学校赛的c题 解析:起先是用stack写的模 ...

最新文章

  1. 30个实用的Python脚本(请收藏)
  2. Java开发命名规范总结
  3. 关于tcp和http
  4. object references an unsaved transient instance - save the transient instance before flushing .
  5. 【Android】资源加载过程
  6. Spring Data JPA 查询方法支持的关键字
  7. Effective C++学习第二天
  8. Docker中Maven私服的搭建
  9. 美股,港股和A股三者之间的关系和差别
  10. PyTorch入门-深度学习回顾和PyTorch简介
  11. Juniper防火墙的日志记录一个的问题
  12. Bailian2909 字符串加空格【指针】
  13. jQuery设置文本框回车事件
  14. CMD获取当前目录的绝对路径
  15. linux安装后root密码错误,linux新安装后root密码设置
  16. 脱库站库分离渗透解决MySQL禁止外连
  17. proteus三输入与门_proteus元件对照
  18. 下行法求最小割集案例_故障树分析方法(FTA)
  19. 【C语言】扫雷(递归展开 + 标记功能)
  20. Scan Context回环检测解读和使用

热门文章

  1. matlab里矩阵相除,Matlab中的矩阵除法有问题???
  2. 我的世界java手机版下载1.15_我的世界java版20w16a
  3. mysql特效_MySQL树 – 前端开发,JQUERY特效,全栈开发,vue开发
  4. Redis之跳跃表(面试重点容易考)
  5. html列表穿插广告怎么实现,基于innerHTML中的script广告实现代码[广告全部放在一个js里面]...
  6. python序列类型有_Python序列类型
  7. 7、Linux中文件类型、文件属性
  8. 参考文献中的字母含义
  9. mysql截取字符串函数left和right和substring和substring_index
  10. Java源码分析--Enum