Steam编程区解谜游戏A=B全解(二)

第二章(关键字)

2-0-0 章节目录

编辑切换为居中

2-0 章节目录

2-0-1 return

编辑

2-0-1 哇哦,更新了

那么面对教授的质疑,为了实现输出一个helloworld,我们的作者同学也是加急更新。

编辑切换为居中

2-0-1 新的关键字return

编辑切换为居中

2-0-1 括号

新加入的这个return呢,大概是给我们提供了提前终止程序的能力,也使得我们的程序得以在不同情况下走向不同的出口。

2-1 你好,世界

编辑切换为居中

2-1 你好,世界

说来有趣,其实最开始我和我的舍友想到的都是三行的解法,即:

a=(return)helloworld

b=(return)helloworld

c=(return)helloworld

也是因为没想到空(")在A=B这门语言里也算是一个字串吧,倒也是可以实现无条件返回。

2-0-2 教授的回复

编辑

2-1-1 教授的回复

看来教授不怎么买账emm

2-2 AAA

编辑切换为居中

2-2 AAA

那么这道题就是比较典型的只和某一些字母有关,所以只要把其他闲人赶走就很好做了,然后在判断出不存在aaa的时候返回一个false就好了。

2-3 恰好三个

编辑切换为居中

2-3 恰好三个

这道题呢,也是不那么复杂的类型,主要原因是他不在乎字母之间的区别,也就是说这道题是由一个字母组成还是26个字母组成毫无影响。只要一视同仁地对待abc,然后四个字母那里截断一下,再判断字母数不是3返回FALSE就完事了。

2-4 余数

编辑切换为居中

2-4 余数

题目类型同上嗷!转化成一样的字母以后,用“aaa=”这个式子逐3逐3地缩短原式,剩下的就是余数啦!

然后这里大家可以想一想长度除以x的余数要怎么求,以及求法的关键是什么。

2-0-3 天天真真

编辑切换为居中

2-0-3 天天真真

某种程度上确实挺幽默的~

2-5 奇数

编辑切换为居中

2-5 奇数

一般对于这种不怎么在乎字母之间的关系的题目,都可以先用这前三行去排个序,把abc分别聚集起来。然后就是怎么去设置逻辑呢?只有确定了abc三个字母出现的次数都不是正偶数才能返回true,所以true的返回我们放到最后,在中间我们发现一个不合格的马上打断返回false。

那么怎么样去确定某个字母出现的次数不是正偶数呢?其实在1-4我们有一个小的延展:如何删除长度大于x的连续的a?再结合一下2-4的求余方法,或会有点思路。

编辑切换为居中

1-4 小拓展

大概我们需要做的是处理字串长度不是正偶数这个条件,那么在2-4里面我们知道了求余数的方法,但是直接套进我们这道题用“aa=”来处理的话会导致无法分辨正偶数和0。这个时候我们在注意一下1-4中的“下限控制”这个词,仔细一想要是把下限控制在1,是不是就可以区分开正偶数和0了?

在上一题中,我觉得大家会想到的求长度除以x的余数的答案可能是“x个a=”,求多少的余数左边就有多少个a就行了,但是实际上问题的关键并不是左边有多少个a,而是等号左右a的个数之差,也即每执行一次语句减少多少个a,而这么做,顺便也可以使得保留字段长度在(左串长-1)和(右串长)之间。

那么这道题的处理方法也就呼之欲出了啊:“aaa=a”。

另外以下是我最初的解法(老软工人第一眼就是未知数),稍微有点长,前三行也是排序,大家有兴趣可以瞅两眼。

编辑切换为居中

2-5 另解

2-6 独一无二

编辑切换为居中

2-6 独一无二

怎么说呢,不知道大家对化学有多少了解,还记不记得官能团保护这么一种有机合成技巧,比较经典的用缩酮反应保护羰基,然后在度过了可能破坏它的环境之后再加酸水解返回原来的羰基。其实这道题也是这样。

编辑切换为居中

保护羰基

一个字母与其相邻字母不同,仔细想想也就孤零零的一个字母,旁边都不是他兄弟,也就是不连续的字母。所以主要的任务就是区分开连续的字母和单个的字母,连续,这个词也见了不少次了吧,“aa=a”,区分,那么下限得大于一,于是乎“aaa=aa”就来了。

然后我们就成功地把所有连续的a都简化成了aa这个串,剩下的就都是单独的字母咯。由于一视同仁,我们就把他们全部变成t去统计t的数目就可以了,然鹅直接a=t又会把aa中的a也变成t,所以这时候就要先给aa伪装一下:aa=r,这一步之后再去执行a=t就没有干扰了,然后r=一波过河拆桥,直接判断结果即可。

2-7 上升

编辑切换为居中

2-7 上升

一般而言这种需要考虑到单个字母聚集性质的题目,我们还是先排个序。

其实写的时候我是先写的2-8,2-9解析再写的2-7,所以有些重复的东西可能会在下面,并且我好想也觉得这道题应该放在最后?

这道题,只有在数目a<b<c的时候才输出成立,按照相邻比较的方法我们大概有两种思路:先a和b比再b和c比,或者先b和c比再a和b比。我这里是选了后者,前者我也小试了一下,好像麻烦一点。

然后站在2-8和2-9的基础上看我觉得这个思路就平平无奇了,排序,掩蔽,搬运似乎可以稳定解决这一类题目。t还是b的另一种化身。两次比较完之后之后b(t)和c都有剩余而且没有a才是正确结果,然后就是要注意到假如啥也不剩了说明b和c一样多,要返回一个false。

然后这个解法没有达到8的挑战长度,但是这个方法是对任意长度的输入字串都是有效的,我也不是那么愿意去采用一些半枚举的剪枝压缩,暂时也没有什么更好的普适解法,那就先这样好了。

2-8 最多

编辑切换为居中

2-8 最多

排序大法好。

然后放到一般情况来说,我们要怎么比较三个数的大小呢?肯定只能两个两个去比,直到能够确认结果。那么最坏的情况下,我们需要比较几次呢?三次,比方说xyz三个数,我们先比较得出x>y,然后再比yz得出z>y,但是这时我们还是无法判断x和z的大小,所以还需要再比较一次。所以比较三次,我们一定可以得出结果。

在排序之后,我们要怎么进行比较呢?可以用第一章写过的捆绑升天法“ab=”,但是这样有什么问题呢?ab互消确实可以用于比较ab的多少,但是这样我们势必会失去其中较少的一个,也没法用较多的一个和另一个字母去比对。这个时候(离子)掩蔽就很有用了。

请看代码的4~6行,这三行就可以实现这样一些功能:首先实现了b和c的比较:如果c比b多,那么c会有剩余,并且剩余的数目就是c比b多的数目,方便后续与a的比较;如果c比b少或者二者一样多呢,在这场争多的比赛中c就没有参赛资格了,销声匿迹对a和b的最终角逐也没有任何影响。其次是b的信息完全保留,只是全部变成了t,让我们得以接下来继续和a比较。其中bt=tb这句话呢也算是一种排序,不过我更倾向于比喻为清理某个反应界面上的生成,以便让反应继续进行下去。

编辑切换为居中

2-8 反应界面(不是)

后面的比较就不需要要进行这种保护了,直接用a和b的转世t去比,再用a和可能存在的c比一下,剩下的就是最多的字母了!(剩余字母的个数是最多和第二多字母的字数差)

2-9 最少

编辑切换为居中

2-9 最少

和2-8一样,上来就是一个排序。

然后类似的也用掩蔽的方法将ab进行比较,但是问题在于这次我们要找的是最少的字母,如果也来一句b=t那么假如a比b少的话a的信息就完全丢失了。不这么做的话,在4~5行完成之后t就代表了a和b中较少的那一个,a和b的剩余字母则是多的那一方比少的那一方多出的字母个数,并且此时我们已经把t搬到了和c相邻的地方,那显而易见接下来就是对于t和c的比较。

和上一题一样,玩到后面就不演了,直接用t和c对消,t代表的是a和b中的小者,假如结果中c没了那么显然c就是最小的那个。那么假如c有富余呢?前面一定还会剩下某一种字母(题目说了一定会有唯一最少的),那么三个字母里面缺失的那个,就是最少的字母啦!

另外下面是别处看到的一个解法,也蛮有意思的,不过好像是只能在题目给的限制条件之下才能使用。有兴趣的朋友可以研究一下。

编辑切换为居中

2-9 另解

2-0-4 不行

编辑切换为居中

2-0-4 不行

这要是行了,还会有接下来的章节吗?

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值