2018第九届届蓝桥杯国赛回顾(真题解析)


**本博所有内容都在个人博客 橙寂博客

序言

参加蓝桥杯糊里糊涂拿了个省一,然后糊里糊涂进京了,5月25号上午出发去北京,然后班机误点导致晚上6点才到北京。第二天就考试然后回去。这次北京行真是来也匆匆去也匆匆。唯一的体验就是挤了下北京的地铁,逛了一下北大(别人家的学校),住了个250多的标间(这个标间是真的很标间了),捡了这个国三(幸亏拿了个奖不然这次北京行也太惨了)这就是我的第一次北京行。

赛制

蓝桥杯国赛java类是考6题。考试时间4小时

  1. 结果填空 (满分11分)
  2. 结果填空 (满分29分)
  3. 代码填空 (满分25分)
  4. 程序设计(满分49分)
  5. 程序设计(满分81分)
  6. 程序设计(满分105分)
    我能告诉各位参赛选手的56题真的很难,得全分很难。但是能捡的分。所以一定确保前面四个能对。前面四个全对,后面得点分没准就国一了。起码能国二。所以重点就是前四题。
年龄问题(一)

s夫人一向很神秘。这会儿有人问起她的年龄,她想了想说:
“20年前,我丈夫的年龄刚好是我的2倍,而现在他的年龄刚好是我的1.5倍”。

你能算出s夫人现在的年龄吗?

注意,需要提交的是一个整数,不要填写任何多余的内容。

题解:这个题目送分题,列个方程 20年前女x 男2x (x+20)*1.5=2x+20. 得x=20 所以答案是20所以这个题目不要去写代码直接算就好了。小学4年级的奥数题得不到分那就没辙了。

海盗与金币

12名海盗在一个小岛上发现了大量的金币,后统计一共有将近5万枚。
登上小岛是在夜里,天气又不好。由于各种原因,有的海盗偷拿了很多,有的拿了很少。
后来为了“均贫富”,头目提出一个很奇怪的方案:
每名海盗都把自己拿到的金币放在桌上。然后开始一个游戏。
金币最多的海盗要拿出自己的金币来补偿其他人。
补偿的额度为正好使被补偿人的金币数目翻番(即变为原来的2倍)。
游戏要一直进行下去,直到无法完成。
(当金币数最多的不只一个人或最多金币的人持有金币数不够补偿他人的)

游戏就这样紧张地进行了,一直进行了12轮,恰好每人都“放血”一次,
更离奇的是,刚好在第12轮后,每个人的金币数居然都相等了!! 这难道是天意吗?

请你计算,游戏开始前,所有海盗的初始金币数目,从小到大排列,中间有一个空格分开。

答案形如:
8 15 29 58 110 …
当然,这个不是正确答案。

注意:
需要提交的是一行空格分开的整数,不要提交任何多余的内容。
分隔符要用一个西文的空格,不要用其它符号(比如逗号,中文符号等)

题解:这个题目很类似跟省赛的一题,第一时间都是暴力破解,但是还是要有规律的暴力不然程序就死了。这个数一定是12的倍数,所以大家可以从这入手。显然是12个人按顺序为其余11人加倍,什么样的顺序无所谓,显然最后一个补偿其它人的人在之前已经被补偿了11次,通过题意每人都补偿了其他人一次,所以第十二个人补偿完以后12个人的金币数都相等了,设为d,那么第十一次时,含有金币最多的人也就是最后进行补偿其他人的人含有的金币数一定是(1<<11)的倍数,被补偿就是翻倍,它翻倍了11次呢,所以说被补偿11次后他的金币数其实是d + 11*d/2,这个很好理解,他要给其他人补偿,最后所有人都是d,包括他自己,那么推到上一次就是其他人的和的一半是属于它的,所以d + 11 * d / 2 = x * (1 << 11),x是未知数,我们要保证12 * d <= 50000,根据题目应该是这个意思,这样的话其实满足条件的x只有13,然后d就是4096,反过来就可以推出最初他们的金币数。

正确答案:13 25 49 97 193 385 769 1537 3073 6145 12289 24577

全排列

对于“1234”,应该输出(一共4!=24行):
1234
1243
1324
1342
1423
1432
2134
2143
2314
2341
2413
2431
3124
3142
3214
3241
3412
3421
4123
4132
4213
4231
4312
4321

下面是实现程序,请仔细分析程序逻辑,并填写划线部分缺少的代码。

// 轮换前k个,再递归处理

import java.util.*;
public class A
{
	static void permu(char[] data, int cur){
		if(cur==data.length-1){
			System.out.println(new String(data));
			return;
		}
		
		for(int i=cur; i<data.length; i++){
			char tmp = data[i]; 
			for(int j=i-1; j>=cur; j--) data[j+1] = data[j];
			data[cur] = tmp;			

			permu(data, cur+1);			

			tmp = data[cur]; 
			__________________________________________ ;
			data[i] = tmp;			
		}
	}
	
	static void permu(String x){
		permu(x.toCharArray(),0);
	}
	
	public static void main(String[] args){
		permu("1234");
	}
}

请注意:只需要填写划线部分缺少的内容,不要抄写已有的代码或符号。

思路:这题是全排列,做这题的思路先把代码复制上去,然后运行。这时你会发现这题和我们经常做的题目有点不一样,但是本质是一样的。仔细看他的代码他递归前做了个for循环for(int j=i-1; j>=cur; j–) data[j+1] = data[j];理解全排列的本质的话这答案就很清晰了我们需要填的肯定跟这个是一样的 for(int j=cur; j<i; j++) data[j] = data[j+1];

正确答案: for(int j=cur; j<i; j++) data[j] = data[j+1];

约瑟夫环

n 个人的编号是 1~n,如果他们依编号按顺时针排成一个圆圈,从编号是1的人开始顺时针报数。
(报数是从1报起)当报到 k 的时候,这个人就退出游戏圈。下一个人重新从1开始报数。
求最后剩下的人的编号。这就是著名的约瑟夫环问题。

本题目就是已知 n,k 的情况下,求最后剩下的人的编号。

题目的输入是一行,2个空格分开的整数n, k
要求输出一个整数,表示最后剩下的人的编号。

约定:0 < n,k < 1百万

例如输入:
10 3

程序应该输出:
4

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。

思路:这题我是用数组做的,然后按照他这逻辑去做,但是数据量一大就出不来了。所以这题我当时应该是没得满分。

答案:我在网上找到这篇感觉写的不错约瑟夫环的几种实现方式

交换次数

IT产业人才需求节节攀升。业内巨头百度、阿里巴巴、腾讯(简称BAT)在某海滩进行招聘活动。
招聘部门一字排开。由于是自由抢占席位,三大公司的席位随机交错在一起,形如:
ABABTATT,这使得应聘者十分别扭。
于是,管理部门要求招聘方进行必要的交换位置,使得每个集团的席位都挨在一起。即最后形如:
BBAAATTT 这样的形状,当然,也可能是:
AAABBTTT 等。

现在,假设每次只能交换2个席位,并且知道现在的席位分布,
你的任务是计算:要使每个集团的招聘席位都挨在一起需要至少进行多少次交换动作。

输入是一行n个字符(只含有字母B、A或T),表示现在的席位分布。
输出是一个整数,表示至少交换次数。

比如,输入:
TABTABBTTTT

程序应该输出:
3

再比如,输入:
TTAAABB

程序应该输出:
0

我们约定,输入字符串的长度n 不大于10万

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。

思路:这题我是通过全排列做的,先做好模板aabbtt ttbbaa ttaabb等模板 然后去全排列。查询符合模板次数最少的。测试题是对的。这题挺难的我想了好久。耗了我蛮多时间网上也没找到特别有用的方案。

标自描述序列

小明在研究一个序列,叫Golomb自描述序列,不妨将其记作{G(n)}。这个序列有2个很有趣的性质:

  1. 对于任意正整数n,n在整个序列中恰好出现G(n)次。
  2. 这个序列是不下降的。

以下是{G(n)}的前几项:

n 1 2 3 4 5 6 7 8 9 10 11 12 13
G(n) 1 2 2 3 3 4 4 4 5 5 5 6 6

给定一个整数n,你能帮小明算出G(n)的值吗?

一个整数n。

对于30%的数据,1 <= n <= 1000000
对于70%的数据,1 <= n <= 1000000000
对于100%的数据,1 <= n <= 2000000000000000

一个整数G(n)

【样例输入】
13

【样例输出】
6

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。

思路:这题我的理解是个找规律的题目,要做这题先找出规律。由题目可知每个n在个G(n)出现了n次比如1出现了1次 2出现了2次 3出现了2次4出现三次 。看这个应该会很清晰。
n 1 2 3 4 5 6 7 8 9 10 11 12 13
G(n) 1 2 2 3 3 4 4 4 5 5 5 6 6

题解:自描述序列

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值