蓝桥杯 2018年国赛真题(Java 大学C组)
标题:年龄问题
题目:
s夫人一向很神秘。这会儿有人问起她的年龄,她想了想说:
"20年前,我丈夫的年龄刚好是我的2倍,而现在他的年龄刚好是我的1.5倍"。
你能算出s夫人现在的年龄吗?
注意,需要提交的是一个整数,不要填写任何多余的内容。
代码:
循环加判断直接输出。
import java.util.*;
public class Main
{
public static void main(String args[])
{
for (int i = 20; i <=100; i++) {
for (int j = 20; j <=200; j++) {
if ((j-20)==(i-20)*2) {
if (j==i*1.5) {
System.out.println(i);
}
}
}
}
}
}
答案:40
标题:海盗与金币
题目:
12名海盗在一个小岛上发现了大量的金币,后统计一共有将近5万枚。
登上小岛是在夜里,天气又不好。由于各种原因,有的海盗偷拿了很多,有的拿了很少。
后来为了“均贫富”,头目提出一个很奇怪的方案:
每名海盗都把自己拿到的金币放在桌上。然后开始一个游戏。
金币最多的海盗要拿出自己的金币来补偿其他人。
补偿的额度为正好使被补偿人的金币数目翻番(即变为原来的2倍)。
游戏要一直进行下去,直到无法完成。
(当金币数最多的不只一个人或最多金币的人持有金币数不够补偿他人的)
游戏就这样紧张地进行了,一直进行了12轮,恰好每人都“放血”一次,
更离奇的是,刚好在第12轮后,每个人的金币数居然都相等了!! 这难道是天意吗?
请你计算,游戏开始前,所有海盗的初始金币数目,从小到大排列,中间有一个空格分开。
答案形如:
8 15 29 58 110 ...
当然,这个不是正确答案。
注意:
需要提交的是一行空格分开的整数,不要提交任何多余的内容。
分隔符要用一个西文的空格,不要用其它符号(比如逗号,中文符号等)
代码:
借鉴于大佬的思路。
import java.util.Arrays;
public class P1_海盗与金币 {
public static void main(String[] args) {
int[] gold = new int[12];
// 第12轮所有人都相等的金币数d
Arrays.fill(gold, 4096);
// 12个海盗
for (int i = 0; i < 12; i++) {
int sum = 0;
// 其他海盗补偿给当前海盗
for (int j = 0; j < 12; j++) {
if (i == j) continue;
gold[j] /= 2;
sum += gold[j];
}
gold[i] += sum;
}
String ans = Arrays.toString(gold).replaceAll(",", " ");
System.out.println(ans.substring(1, ans.length()-1));
}
}
标题:全排列
题目:
对于某个串,比如:“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
下面是实现程序,请仔细分析程序逻辑,并填写划线部分缺少的代码。
代码:
网上的大佬太强了。
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(int j=cur+1; j<=i; j++) data[j-1] = data[j]
标题:约瑟夫环
题目:
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,否则按无效代码处理。
代码:
import java.util.Scanner;
public class four {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt(), k = in.nextInt();
int p = 0;
for (int i = 2; i <= n; i++) {
p = (p + k) % i;
}
System.out.println(p + 1);
}
标题:交换次数
题目:
IT产业人才需求节节攀升。业内巨头百度、阿里巴巴、腾讯(简称BAT)在某海滩进行招聘活动。
招聘部门一字排开。由于是自由抢占席位,三大公司的席位随机交错在一起,形如:
ABABTATT,这使得应聘者十分别扭。
于是,管理部门要求招聘方进行必要的交换位置,使得每个集团的席位都挨在一起。即最后形如:
BBAAATTT 这样的形状,当然,也可能是:
AAABBTTT 等。
现在,假设每次只能交换2个席位,并且知道现在的席位分布,
你的任务是计算:要使每个集团的招聘席位都挨在一起需要至少进行多少次交换动作。
输入是一行n个字符(只含有字母B、A或T),表示现在的席位分布。
输出是一个整数,表示至少交换次数。
比如,输入:
TABTABBTTTT
程序应该输出:
3
再比如,输入:
TTAAABB
程序应该输出:
0
我们约定,输入字符串的长度n 不大于10万
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String s=sc.next();
sc.close();
char[][] c= {
{'B','A','T'},
{'B','T','A'},
{'A','B','T'},
{'A','T','B'},
{'T','A','B'},
{'T','B','A'},
};
int res=Integer.MAX_VALUE;
for (int i = 0; i < 6; i++) {
res=Math.min(res, f(s,c[i][0],c[i][1],c[i][2]));
}
System.out.println(res);
}
static int f(String s,char A,char B,char C) {
int a=0,b=0;
int Abc=0,Ab=0,Ba=0,Bc=0;
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i)==A) a++;
if(s.charAt(i)==B) b++;
}
for (int i = 0; i < a; i++) {
if(s.charAt(i)!=A) Abc++;
if(s.charAt(i)==B) Ab++;
}
for (int i = a; i < a+b; i++) {
if(s.charAt(i)==A) Ba++;
if(s.charAt(i)==C) Bc++;
}
return Abc+Bc+Ba-Math.min(Ab, Ba);
}
}
标题:自描述序列
题目:
小明在研究一个序列,叫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,否则按无效代码处理。
代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
long n = in.nextLong();
List<Long> list = new ArrayList<>();
list.add((long) 0);
list.add((long) 1);
list.add((long) 3);
int j = 2;
for (int i = 2; list.get(i) < 1000000; i++) {
if (list.get(j) < i + 1) {
j++;
}
list.add(j + list.get(i));
}
j = 1;
long yn = 0, gn = 0;
for (long i = 1; i < 2000000000000000l; i++) {
if (i > list.get(j)) j++;
yn += i * j;
gn += j;
if (yn >= n) {
if (yn == n) {
System.out.println(gn);
return;
} else {
System.out.println(gn - (yn - n) / i);
return;
}
}
}
}
}
后几个题的代码,都是借鉴于网上的大佬的方法,并不是我的方法。国赛题太难了,我的智商不在线。