当前位置:   article > 正文

蓝桥杯历年真题JAVA版-2015年蓝桥杯省赛- Java组

蓝桥杯历年真题JAVA版-2015年蓝桥杯省赛- Java组

第1题——星系炸弹

(1)题目描述

在X星系的广袤空间中漂浮着许多X星人造“炸弹”,用来作为宇宙中的路标。
每个炸弹都可以设定多少天之后爆炸。
比如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16日爆炸。
有一个贝塔炸弹,a年b月c日放置,定时为n天,请你计算它爆炸的准确日期。

输入格式:

输入存在多组数据,每组数据输入一行,每一行输入四个正整数a,b,c,n
输入保证日期在1000-01-01到2020-01-01之间,且日期合法。
n不超过1000

输出格式:

请填写该日期,格式为 yyyy-mm-dd  即4位年份2位月份2位日期。

比如:2015-02-19
请严格按照格式书写。不能出现其它文字或符号。
 

输入样例:

2015 1 1 15
2014 11 9 1000

输出样例 :
2015-01-16
2017-08-05

(2)解题代码

  1. /**
  2. *
  3. * @param a 年
  4. * @param b 月
  5. * @param c 日
  6. * @param n 天数
  7. */
  8. public static void func1(int a, int b, int c, int n) {
  9. // 参数校验
  10. if ((a < 1000 || a > 2020) || (b < 0 || b > 12) || (c < 0 || c > 31) || (n < 0 || n > 1000)) {
  11. System.out.println("输入不合法");
  12. return;
  13. }
  14. Calendar calendar = Calendar.getInstance();
  15. calendar.set(a, b - 1, c);
  16. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  17. // n天后
  18. calendar.add(Calendar.DAY_OF_YEAR, n);
  19. System.out.println(sdf.format(calendar.getTime()));
  20. }

(3)输出结果


 第2题——牌型种数

(1)题目描述

小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。
这时,小明脑子里突然冒出一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序
自己手里能拿到的初始牌型组合一共有多少种呢?

(2)解题代码

  1. int sum = 0;
  2. /**
  3. *
  4. * @param pos 牌型1-13
  5. * @param cnt 手里牌的数目
  6. */
  7. public void func2(int pos, int cnt) {
  8. if (cnt == 13) {
  9. sum++;
  10. return;
  11. }
  12. if (pos == 13) {
  13. return;
  14. }
  15. // 取两者中的小值
  16. int min = Math.min(13 - cnt, 4);
  17. for (int i = 0; i <= min; i++) {
  18. func2(pos + 1, cnt + i);
  19. }
  20. }

(3)运行结果


第3题——垒骰子

(1)题目描述

赌圣atm晚年迷恋上了垒骰子,就是把骰子一个垒在另一个上边,不能歪歪扭扭,要垒成方柱体。
经过长期观察,atm 发现了稳定骰子的奥秘:有些数字的面贴着会互相排斥!
我们先来规范一下骰子:1 的对面是 4,2 的对面是 5,3 的对面是 6。
假设有 m 组互斥现象,每组中的那两个数字的面紧贴在一起,骰子就不能稳定的垒起来。 
atm想计算一下有多少种不同的可能的垒骰子方式。
两种垒骰子方式相同,当且仅当这两种方式中对应高度的骰子的对应数字的朝向都相同。
由于方案数可能过多,请输出模 10^9 + 7 的结果。

输入格式:

输入存在多组测试数据,对于每组数据:
第一行两个整数 n m(0<n<10^9,m<=36)
n表示骰子数目
接下来 m 行,每行两个整数 a b ,表示 a 和 b 数字不能紧贴在一起。 

输出格式:

对于每组测试数据,输出一行,只包含一个数,表示答案模 10^9 + 7 的结果。


输入样例 :
2 1

1 2

输出样例:
544

(2)解题代码

  1. public static int n, m;
  2. public static int[][] oje = new int[7][7];
  3. public static int count = 0;
  4. public static int[] dui = { 0, 4, 5, 6, 1, 2, 3 };
  5. public static int mode = 1000000007;
  6. public static void dfs(int i, int di) {
  7. if (i == n) {
  8. count++;
  9. if (count > mode)
  10. count -= mode;
  11. } else {
  12. if (di == -1) {
  13. for (int j = 1; j < 7; j++) {
  14. dfs(i + 1, dui[j]);
  15. }
  16. } else {
  17. for (int j = 1; j < 7; j++) {
  18. if (oje[j][di] == 0) {
  19. dfs(i + 1, dui[j]);
  20. }
  21. }
  22. }
  23. }
  24. }
  25. public void func3() {
  26. Scanner in = new Scanner(System.in);
  27. n = in.nextInt();
  28. m = in.nextInt();
  29. int a, b;
  30. for (int i = 0; i < m; i++) {
  31. a = in.nextInt();
  32. b = in.nextInt();
  33. oje[a][b] = 1;
  34. oje[b][a] = 1;
  35. }
  36. dfs(0, -1);
  37. int ans = 1;
  38. for (int i = 0; i < n; i++) {
  39. ans = (ans * 4) % mode;
  40. }
  41. System.out.println((count * ans) % mode);
  42. in.close();
  43. }

(3)运行结果


第4题——灾后重建

(1)题目描述

Pear市一共有N(<=50000)个居民点,居民点之间有M(<=200000)条双向道路相连。
这些居民点两两之间都可以通过双向道路到达。
这种情况一直持续到最近,一次严重的地震毁坏了全部M条道路。
震后,Pear打算修复其中一些道路,修理第i条道路需要Pi的时间。
不过,Pear并不打算让全部的点连通,而是选择一些标号特殊的点让他们连通。
Pear有Q(<=50000)次询问,每次询问,他会选择所有编号在[l,r]之间,并且 编号 mod K  = C 的点,修理一些路使得它们连通。
由于所有道路的修理可以同时开工,所以完成修理的时间取决于花费时间最长的一条路,即涉及到的道路中Pi的最大值。
你能帮助Pear计算出每次询问时需要花费的最少时间么?
这里询问是独立的,也就是上一个询问里的修理计划并没有付诸行动。

输入格式:

第一行三个正整数N、M、Q,含义如题面所述。
接下来M行,每行三个正整数Xi、Yi、Pi,表示一条连接Xi和Yi的双向道路,修复需要Pi的时间。
可能有自环,可能有重边。1<=Pi<=1000000。
接下来Q行,每行四个正整数Li、Ri、Ki、Ci,表示这次询问的点是[Li,Ri]区间中所有编号Mod Ki=Ci的点。
保证参与询问的点至少有两个。

输出格式:

输出Q行,每行一个正整数表示对应询问的答案。

输入样例:

7 10 4
1 3 10
2 6 9
4 1 5
3 7 4
3 6 9
1 5 8
2 7 4
3 2 10
1 7 6
7 6 9
1 7 1 0
1 7 3 1
2 5 1 0
3 7 2 1

输出样例:
9
6
8
8

(2)解题代码

  1. public static int N, M, Q;
  2. public static Edge[] edges;
  3. public static UnionFind uf;
  4. public static ArrayList<Integer> costs = new ArrayList<Integer>();
  5. /**
  6. * 逐步加入边到最小生成树中,若加入该边后使得[l,r]中余mod等于c的点连通,则输出最后加入的边的cost
  7. *
  8. * @param l 左边界
  9. * @param r 右边界
  10. * @param mod 模
  11. * @param c 余数
  12. */
  13. public static void buildMst(int l, int r, int mod, int c) {
  14. for (int i = 0; i < uf.ufNodes.length; i++) {
  15. uf.ufNodes[i].parent = null;
  16. }
  17. for (int i = 0; i < M; i++) {
  18. Edge edge = edges[i];
  19. int from = edge.from;
  20. int to = edge.to;
  21. int cost = edge.cost;
  22. // 如果该边加入不会构成环,则将其加入最小生成树
  23. if (uf.find(from) == uf.find(to)) {
  24. continue;
  25. } else {
  26. uf.merge(from, to);
  27. }
  28. // 判断要关注的所有点是否连通
  29. boolean isOk = true;
  30. UnionFind.UFNode parent = null;
  31. for (int j = l; j <= r; j++) {
  32. if (j % mod == c) {
  33. if (parent == null) {
  34. parent = uf.find(j); // 第一个关注点的老大
  35. } else {
  36. if (parent != uf.find(j)) { // 没有连通
  37. isOk = false;
  38. break;
  39. }
  40. }
  41. }
  42. }
  43. // 如果isOk为true,说明最后加的一条边即为使得要关注的点连通的边,输出cost则为最大花费
  44. if (isOk) {
  45. costs.add(Integer.valueOf(cost));
  46. break;
  47. }
  48. }
  49. }
  50. public static class Edge implements Comparable<Edge> {
  51. public int from; // 边的起点
  52. public int to; // 边的终点
  53. public int cost; // 代价
  54. public Edge(int from, int to, int cost) {
  55. super();
  56. this.from = from;
  57. this.to = to;
  58. this.cost = cost;
  59. }
  60. public Edge() {
  61. }
  62. @Override
  63. public int compareTo(Edge o) {
  64. return cost > o.cost ? 1 : (cost == o.cost) ? 0 : -1;
  65. }
  66. }
  67. // 并查集
  68. public static class UnionFind {
  69. UFNode[] ufNodes;
  70. int count;
  71. public static class UFNode {
  72. UFNode parent;
  73. }
  74. public UnionFind(int count) {
  75. ufNodes = new UFNode[count];
  76. for (int i = 0; i < ufNodes.length; i++) {
  77. ufNodes[i] = new UFNode();
  78. }
  79. this.count = count;
  80. }
  81. // 查找并压缩查找路径
  82. UFNode find(int i) {
  83. UFNode node = ufNodes[i];
  84. // 本身就是树根
  85. if (node == null) {
  86. return node;
  87. }
  88. // set存储不是根节点的UFNode,之后用来压缩路径
  89. Set<UFNode> set = new HashSet<UFNode>();
  90. // 寻找树根
  91. while (node.parent != null) {
  92. set.add(node);
  93. node = node.parent;
  94. }
  95. // 压缩路径,让某个并查集的所有元素的parent为该集合的老大
  96. for (UFNode ufNode : set) {
  97. ufNode.parent = node;
  98. }
  99. return node;
  100. }
  101. // 合并两个并查集
  102. void merge(int a, int b) {
  103. find(b).parent = find(a);
  104. }
  105. }
  106. public void func4() {
  107. Scanner sc = new Scanner(System.in);
  108. N = sc.nextInt();
  109. M = sc.nextInt();
  110. Q = sc.nextInt();
  111. edges = new Edge[M];
  112. uf = new UnionFind(N + 1);
  113. for (int i = 0; i < edges.length; i++) {
  114. int a = sc.nextInt();
  115. int b = sc.nextInt();
  116. int cost = sc.nextInt();
  117. edges[i] = new Edge(a, b, cost);
  118. }
  119. Arrays.sort(edges); // 将边集排序
  120. for (int i = 0; i < Q; i++) {
  121. int l = sc.nextInt();
  122. int r = sc.nextInt();
  123. int mod = sc.nextInt();
  124. int c = sc.nextInt();
  125. buildMst(l, r, mod, c);
  126. }
  127. for (Integer i : costs) {
  128. System.out.println(i);
  129. }
  130. sc.close();
  131. }

(3)运行结果


第5题——加法边乘法

(1)题目描述

我们都知道:1+2+3+ ... + 49 = 1225
现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015
比如:
1+2+3+...+10*11+12+...+27*28+29+...+49 = 2015 就是符合要求的答案。
请你寻找另外一个可能的答案,并把位置靠前的那个乘号左边的数字提交。
(对于示例,就是提交10)。

输出格式:注意:需要你提交的是一个整数,不要填写任何多余的内容。

(2)解题代码

  1. public void func5() {
  2. int a, b, c, d;
  3. for (int i = 1; i <= 49; i++) {
  4. a = i;
  5. b = i + 1;
  6. for (int j = i + 2; j <= 49; j++) {
  7. c = j;
  8. d = j + 1;
  9. if (a * b + c * d - (a + b) - (c + d) == 790 && a != 10) {
  10. System.out.println(a);
  11. break;
  12. }
  13. }
  14. }
  15. }

(3)运行结果


第6题——移动距离

(1)题目描述

X星球居民小区的楼房全是一样的,并且按矩阵样式排列。
其楼房的编号为1,2,3... 当排满一行时,从下一行相邻的楼往反方向排号。
比如:当小区排号宽度为6时,开始情形如下:

1  2  3  4  5  6
12 11 10 9  8  7
13 14 15 ..... 

我们的问题是:已知了两个楼号m和n,需要求出它们之间的最短移动距离
(不能斜线方向移动)

输入格式:

输入存在多组测试数据
输入为3个整数w m n,空格分开,都在1到10000范围内
w为排号宽度,m,n为待计算的楼号。

输出格式:

要求输出一个整数,表示m n 两楼间最短移动距离。

输入样例:

6 8 2
4 7 20

输出样例:
4

5

(2)解题代码

  1. public int[] zb(int m, int w) {
  2. int sz[] = new int[2];
  3. int x = 0, y = 0;
  4. int a = 0;
  5. if (m % w == 0) {
  6. a = m / w;
  7. } else {
  8. a = m / w + 1;
  9. }
  10. if (a % 2 == 0) {
  11. x = w + 1 - m % w;
  12. y = a;
  13. } else {
  14. x = m % w;
  15. y = a;
  16. }
  17. sz[0] = x;
  18. sz[1] = y;
  19. return sz;
  20. }
  21. public void func6() {
  22. Scanner in = new Scanner(System.in);
  23. List<Integer> result = new ArrayList<>();
  24. for (int i = 0; i < 2; i++) {
  25. int w = in.nextInt();
  26. int m = in.nextInt();
  27. int n = in.nextInt();
  28. int distance = Math.abs((zb(m, w)[1] - zb(n, w)[1])) + Math.abs((zb(m, w)[0] - zb(n, w)[0]));
  29. result.add(distance);
  30. }
  31. result.forEach(System.out::println);
  32. in.close();
  33. }

(3)运行结果


第7题——饮料换购 

(1)题目描述

乐羊羊饮料厂正在举办一次促销优惠活动。
乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去(但不允许暂借或赊账)。
请你计算一下,如果小明不浪费瓶盖,尽量地参加活动。
那么,对于他初始买入的n瓶饮料,最后他一共能喝到多少瓶饮料。 

输入格式:

输入存在多组测试数据
每组测试数据输入一行包含一个正整数n(1<=n<=10000)

输出格式:

对于每组数据输出一行,包含一个整数,表示实际得到的饮料数

输入样例 :

100

101

输出样例 :

149

151

(2)解题代码

  1. public void func7() {
  2. Scanner in = new Scanner(System.in);
  3. int n = in.nextInt();
  4. int a = n;
  5. int num = 0;
  6. while (true) {
  7. num += a / 3;
  8. a = a / 3 + a % 3;
  9. if (a < 3) {
  10. break;
  11. }
  12. }
  13. System.out.println(num + n);
  14. in.close();
  15. }

(3)运行结果

  


第8题——奇妙的数字

(1)题目描述

小明发现了一个奇妙的数字。它的平方和立方正好把0~9的10个数字每个用且只用了一次。你能猜出这个数字是多少吗?

(2)解题代码

  1. public static int ans1, ans2;
  2. public void func8() {
  3. for (int i = 1; i < 100; i++) {
  4. ans1 = i * i;
  5. ans2 = ans1 * i;
  6. String str3 = ans1 + "" + ans2 + "";
  7. char arr[] = str3.toCharArray();
  8. Arrays.sort(arr);
  9. String str = new String(arr);
  10. // 字符串的比较用equals不用==
  11. if (str.equals("0123456789")) {
  12. System.out.println(i);
  13. break;
  14. }
  15. }
  16. }

(3)运行结果


第9题——生命之树

(1)题目描述

在X森林里,上帝创建了生命之树。
他给每棵树的每个节点(叶子也称为一个节点)上,都标了一个整数,代表这个点的和谐值。
上帝要在这棵树内选出一个非空节点集S,使得对于S中的任意两个点a,b,都存在一个点列 {a, v1, v2, ..., vk, b} 
使得这个点列中的每个点都是S里面的元素,且序列中相邻两个点间有一条边相连。
在这个前提下,上帝要使得S中的点所对应的整数的和尽量大。
这个最大的和就是上帝给生命之树的评分。
经过atm的努力,他已经知道了上帝给每棵树上每个节点上的整数。
但是由于 atm 不擅长计算,他不知道怎样有效的求评分。
他需要你为他写一个程序来计算一棵树的分数。

输入格式:

第一行一个整数 n 表示这棵树有 n 个节点。(0<n<=10^5)
第二行 n 个整数,依次表示每个节点的评分。(每个节点的评分不超过10^6)
接下来 n-1 行,每行 2 个整数 u, v,表示存在一条 u 到 v 的边。
由于这是一棵树,所以是不存在环的。

输出格式:

输出一行一个数,表示上帝给这棵树的分数。

输入样例:

5
1 -2 -3 4 5
4 2
3 1
1 2
2 5

输出样例:
8

(2)解题代码

  1. public static int n;// 节点数
  2. public static int[] v;// 节点集合
  3. public static int[][] arr;// 节点边表示集合
  4. public static boolean[] vis;
  5. public static int max = 0;// 节点连接的最大值
  6. public static void dfs(int m) {
  7. if (m == n) {
  8. return;
  9. }
  10. for (int i = 1; i <= n; i++) {
  11. if (vis[i] == false && arr[m][i] != 0) {// vis[i] == false是限界函数,arr[m][i] != 0是约束函数
  12. vis[i] = true;
  13. if (v[m] < (v[m] + v[i])) {
  14. v[m] = v[m] + v[i];
  15. }
  16. max = Math.max(max, v[m]);
  17. dfs(i);
  18. }
  19. }
  20. }
  21. public void func9() {
  22. Scanner in = new Scanner(System.in);
  23. n = in.nextInt();
  24. v = new int[n + 1];
  25. arr = new int[n + 1][n + 1];
  26. vis = new boolean[n + 1];
  27. for (int i = 1; i <= n; i++) {
  28. v[i] = in.nextInt();
  29. }
  30. for (int i = 1; i < n; i++) {
  31. int a = in.nextInt();
  32. int b = in.nextInt();
  33. arr[a][b] = 1;
  34. arr[b][a] = 1;
  35. }
  36. dfs(1);
  37. System.out.println(max);
  38. in.close();
  39. }

(3)运行结果


第10题——三羊献瑞

(1)题目描述

观察下面的加法算式:


其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。
请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容。

(2)解题代码

  1. public void f(int[] a, int[] b, int i) {
  2. // 结束条件
  3. if (i == a.length) {
  4. int x = a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3];
  5. int y = a[4] * 1000 + a[5] * 100 + a[6] * 10 + a[1];
  6. int z = a[4] * 10000 + a[5] * 1000 + a[2] * 100 + a[1] * 10 + a[7];
  7. if (x + y == z) {
  8. if (y / 1000 > 0)
  9. System.out.println(y);
  10. }
  11. return;
  12. }
  13. for (int j = 0; j < b.length; j++) {
  14. if (b[j] != -1) {
  15. a[i] = b[j]; // 取数放进容器a里
  16. b[j] = -1; // 已使用,标记-1
  17. f(a, b, i + 1);
  18. b[j] = a[i]; // 调用结束了,把容器a里的数还回去
  19. }
  20. }
  21. }

(3)运行结果


第11题——打印大X 

(1)题目描述

小明希望用星号拼凑,打印出一个大X,他要求能够控制笔画的宽度和整个字的高度。
为了便于比对空格,所有的空白位置都以句点符来代替。
要求输入两个整数m n,表示笔的宽度,X的高度。


输入格式:
输入存在多组数据
每组测试数据输入一行,包含两个整数,用空格分开
(0<m<n, 3<n<1000, 保证n是奇数)

输出格式:

要求输出一个大X

输入样例:

3 9
4 21

输出样例:

***.....***
.***...***.
..***.***..
...*****...
....***....
...*****...
..***.***..
.***...***.
***.....***
****................****
.****..............****.
..****............****..
...****..........****...
....****........****....
.....****......****.....
......****....****......
.......****..****.......
........********........
.........******.........
..........****..........
.........******.........
........********........
.......****..****.......
......****....****......
.....****......****.....
....****........****....
...****..........****...
..****............****..
.****..............****.
****................****

(2)解题代码

  1. public void func11(int m, int n) {
  2. // 列=n+m-1
  3. int cols = n + m - 1;
  4. char a[][] = new char[n][cols];
  5. if (n > m && m > 0 && n > 3 && n < 1000) {
  6. int i, j;
  7. // 将图形全部初始化为. ,然后再找*的位置
  8. for (i = 0; i < n; i++)
  9. for (j = 0; j < cols; j++)
  10. a[i][j] = '.';
  11. for (i = 0; i < n; i++) {
  12. // 主对角线
  13. for (j = i; j < i + m; j++)
  14. a[i][j] = '*';
  15. // 副对角线
  16. for (j = cols - 1 - i; j >= cols - m - i; j--)
  17. a[i][j] = '*';
  18. }
  19. // 打印图形
  20. for (i = 0; i < n; i++) {
  21. for (j = 0; j < cols; j++)
  22. System.out.print(a[i][j]);
  23. System.out.println();
  24. }
  25. }
  26. }

(3)运行结果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/73635
推荐阅读
相关标签
  

闽ICP备14008679号