2018蓝桥杯国赛Java大学C组真题
【问题描述】A:年龄问题
s夫人一向很神秘。这会儿有人问起她的年龄,她想了想说:
“20年前,我丈夫的年龄刚好是我的2倍,而现在他的年龄刚好是我的1.5倍”。
你能算出s夫人现在的年龄吗?
注意,需要提交的是一个整数,不要填写任何多余的内容。
【分析】
本题比较简单,直接暴力破解即可,不会暴力一个一个数算也可以,不会超过100岁
【代码】
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Main {
/**
* 1.年龄问题
* 【问题描述】
* <p>
* s夫人一向很神秘。这会儿有人问起她的年龄,她想了想说:
* “20年前,我丈夫的年龄刚好是我的2倍,而现在他的年龄刚好是我的1.5倍”。
* 你能算出s夫人现在的年龄吗
*/
public static void main(String[] args) {
long woman =0;
for (long i = 20; i < 300; i++) {
if (i % 2 == 0) {
woman = i / 2;
if ((woman + 20) * 1.5 == (i + 20)) {
woman += 20;
System.out.println((i + 20) + " " + woman);
break;
}
}
}
}
}
【问题描述】B:海盗与金币
12名海盗在一个小岛上发现了大量的金币,后统计一共有将近5万枚。
登上小岛是在夜里,天气又不好。由于各种原因,有的海盗偷拿了很多,有的拿了很少。
后来为了“均贫富”,头目提出一个很奇怪的方案:
每名海盗都把自己拿到的金币放在桌上。然后开始一个游戏。
金币最多的海盗要拿出自己的金币来补偿其他人。
补偿的额度为正好使被补偿人的金币数目翻番(即变为原来的2倍)。
游戏要一直进行下去,直到无法完成。
(当金币数最多的不只一个人或最多金币的人持有金币数不够补偿他人的)
游戏就这样紧张地进行了,一直进行了12轮,恰好每人都“放血”一次,
更离奇的是,刚好在第12轮后,每个人的金币数居然都相等了!! 这难道是天意吗?
请你计算,游戏开始前,所有海盗的初始金币数目,从小到大排列,中间有一个空格分开。
答案形如:
8 15 29 58 110 …
当然,这个不是正确答案。
注意:
需要提交的是一行空格分开的整数,不要提交任何多余的内容。
分隔符要用一个西文的空格,不要用其它符号(比如逗号,中文符号等)
【分析】
题目说有大约5万金币,有12人拿走了,有得多,有的少,但是进行了12轮的分摊,每个人都使其余11人的金币翻倍,正好12人都被放血了,我们直接暴力破解,从45000开始,不能平分12份的直接跳过,可以的话,就假装数组中第一个是最后出血的人,逆转回血,其余11人都给他金币,给自身金币的一半,如果其余11人的金币不够分成两半就停止,不符合,当i=j的时候就跳过,因为自己不用给自己分,到最后都没有不符合的情况,就输出数组
【代码】
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] arr=new int[12];
for (int i=45000;i<=50000;i++){
if (i%12!=0) continue;
Arrays.fill(arr,i/12);
if(help(arr)){
System.out.println(Arrays.toString(arr));
}
}
}
public static boolean help(int[] arr){
for (int i = 0; i <12 ; i++) {
for (int j = 0; j <12 ; j++) {
if (i==j) continue;
if (arr[j]%2!=0) return false;
arr[j]/=2;
arr[i]+=arr[j];
}
}
return true;
}
}
【答案:[13, 25, 49, 97, 193, 385, 769, 1537, 3073, 6145, 12289, 24577]】
【问题描述】C:全排列
对于某个串,比如:“1234”,求它的所有全排列。
并且要求这些全排列一定要按照字母的升序排列。
对于“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
【分析】
【代码】
【问题描述】D:约瑟夫环
n 个人的编号是 1~n,如果他们依编号按顺时针排成一个圆圈,从编号是1的人开始顺时针报数。
(报数是从1报起)当报到 k 的时候,这个人就退出游戏圈。下一个人重新从1开始报数。
求最后剩下的人的编号。这就是著名的约瑟夫环问题。
本题目就是已知 n,k 的情况下,求最后剩下的人的编号。
题目的输入是一行,2个空格分开的整数n, k
要求输出一个整数,表示最后剩下的人的编号。
约定:0 < n,k < 1百万
例如输入:
10 3
程序应该输出:
4
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
【分析】
本题数据达到了百万,所以不能用常规的方法了,首先举例子找规律,当k=3时,n=1时,输出f=1,当n=2时,应输出f=(k+f)%n=0,当输出f为0时,直接输出n即可,即f=n=2,当n=3时,应输出f=(k+f)%n=2,当n=4时,应输出f=(k+f)%n=1,当n=5时…
【代码】
import java.util.Scanner;
public class Main {
static Scanner sr=new Scanner(System.in);
static int n=sr.nextInt();
static int k=sr.nextInt();
public static void main(String[] args) {
if (n==1) {
System.out.println(1);
}else {
help(2, k, 1);
}
}
public static void help(int num,int k,int f){
while (num<=n){
int in=f;
in = (k+in)%num;
if (in==0) in=num;
f=in;
num++;
}
System.out.println(f);
}
}
【问题描述】E:交换次数
IT产业人才需求节节攀升。业内巨头百度、阿里巴巴、腾讯(简称BAT)在某海滩进行招聘活动。
招聘部门一字排开。由于是自由抢占席位,三大公司的席位随机交错在一起,形如:
ABABTATT,这使得应聘者十分别扭。
于是,管理部门要求招聘方进行必要的交换位置,使得每个集团的席位都挨在一起。即最后形如:
BBAAATTT 这样的形状,当然,也可能是:
AAABBTTT 等。
现在,假设每次只能交换2个席位,并且知道现在的席位分布,
你的任务是计算:要使每个集团的招聘席位都挨在一起需要至少进行多少次交换动作。
输入是一行n个字符(只含有字母B、A或T),表示现在的席位分布。
输出是一个整数,表示至少交换次数。
比如,输入:
TABTABBTTTT
程序应该输出:
3
再比如,输入:
TTAAABB
程序应该输出:
0
我们约定,输入字符串的长度n 不大于10万