温馨提示:这篇文章已超过465天没有更新,请注意相关的内容是否还可用!
摘要:第十四届蓝桥杯大赛软件赛省赛(Java 大学C组)是一场面向全国大学生的编程竞赛。该比赛旨在提高大学生的编程能力和算法水平,促进软件行业的发展。比赛采用Java语言,针对大学C组参赛者进行。通过激烈的角逐,参赛者将有机会展示自己的编程技能和创新能力,同时获得荣誉证书和奖金等奖励。
蓝桥杯 2023年省赛真题
Java 大学C组
- 试题 A: 求和
- 试题 B: 分糖果
- 试题 C: 三国游
- 试题 D: 平均
- 试题 E: 填充
- 试题 F: 棋盘
- 试题 G: 子矩阵
- 试题 H: 公因数匹配
- 试题 I: 异或和之差
- 试题 J: 太阳
开胃小菜。
(图片来源网络,侵删)试题 A: 求和
本题总分: 5 5 5 分
【问题描述】
求 1 1 1 (含)至 20230408 20230408 20230408 (含)中每个数的和。
【答案提交】
(图片来源网络,侵删)这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
204634714038436
自然数列求和, 1 + 2 + ⋯ + n = n ( n + 1 ) 2 1+2+\cdots+n=\cfrac {n(n+1)}2 1+2+⋯+n=2n(n+1)。
public class Main { public static void main(String ...args) { new Main().run(); } void run() { System.out.println( 20230408 * (20230408 + 1l) / 2 ); } }
或者迭代答案。
public class Main { public static void main(String ...args) { new Main().run(); } void run() { long ans = 0; for (int i = 1; i public static void main(String ...args) { new Main().run(); } int n = 7, c1 = 9, c2 = 16, l = 2, r = 5; long ans = 0; void dfs(int depth) { if (depth == n) { if (c1 == 0 && c2 == 0) ++ans; } else { for (int i = l; i if (c1 Y+Z 时,我们认为魏国获胜。小蓝想知道游戏结束时如果有其中一个国家获胜,最多发生了多少个事件?
如果不存在任何能让某国获胜的情况,请输出 − 1 −1 −1。
【输入格式】
输入的第一行包含一个整数 n n n。
第二行包含 n n n 个整数表示 A i A_i Ai,相邻整数之间使用一个空格分隔。
第三行包含 n n n 个整数表示 B i B_i Bi,相邻整数之间使用一个空格分隔。
第四行包含 n n n 个整数表示 C i C_i Ci,相邻整数之间使用一个空格分隔。
【输出格式】
输出一行包含一个整数表示答案。
【样例输入】
3 1 2 2 2 3 2 1 0 7
【样例输出】
2
【样例说明】
发生两个事件时,有两种不同的情况会出现获胜方。
发生 1 , 2 1, 2 1,2 事件时蜀国获胜。
发生 1 , 3 1, 3 1,3 事件时吴国获胜。
【评测用例规模与约定】
对于 40 % 40\% 40% 的评测用例, n ≤ 500 n ≤ 500 n≤500;
对于 70 % 70\% 70% 的评测用例, n ≤ 5000 n ≤ 5000 n≤5000;
对于所有评测用例, 1 ≤ n ≤ 1 0 5 , 1 ≤ A i , B i , C i ≤ 1 0 9 1 ≤ n ≤ 10^5,1 ≤ A_i, B_i,C_i ≤ 10^9 1≤n≤105,1≤Ai,Bi,Ci≤109。
贪心
同时考虑三个国家是相当困难的,于是考虑分别求出魏蜀吴分别获胜的话最大事件数,最优答案就是这若干个数中的最大值。
以魏举例,记第 i i i 个事件对魏获胜的贡献为 x i − y i − z i x_i -y_i -z_i xi−yi−zi,按贡献降序重排事件,找到一个 k k k,满足 ∑ i = 1 k x i > ∑ i = 1 k ( y i + z i ) \sum_{i=1}^kx_i >\sum_{i=1}^k(y_i + z_i) ∑i=1kxi>∑i=1k(yi+zi) 且 k k k 尽可能大,若 k s[0] > s[1] + s[2]), greedy((a, b) -> Integer.compare(b.y - b.x - b.z, a.y - a.x - a.z), s->s[1] > s[0] + s[2]), greedy((a, b) -> Integer.compare(b.z - b.x - b.y, a.z - a.x - a.y), s->s[2] > s[0] + s[1]) ) ); } StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); int nextInt() { try { in.nextToken(); } catch (IOException e) { e.printStackTrace(); } return (int) in.nval; } }
试题 D: 平均
时间限制: 3.0 s 3.0\mathrm s 3.0s 内存限制: 512.0 M B 512.0\mathrm{MB} 512.0MB 本题总分: 10 10 10 分
【问题描述】
有一个长度为 n n n 的数组( n n n 是 10 10 10 的倍数),每个数 a i a_i ai 都是区间 [ 0 , 9 ] [0, 9] [0,9] 中的整数。小明发现数组里每种数出现的次数不太平均,而更改第 i i i 个数的代价为 b i b_i bi,他想更改若干个数的值使得这 10 10 10 种数出现的次数相等(都等于 n 10 \frac n{10} 10n ),请问代价和最少为多少。
【输入格式】
输入的第一行包含一个正整数 n n n。
接下来 n n n 行,第 i i i 行包含两个整数 a i , b i a_i, b_i ai,bi,用一个空格分隔。
【输出格式】
输出一行包含一个正整数表示答案。
【样例输入】
10 1 1 1 2 1 3 2 4 2 5 2 6 3 7 3 8 3 9 4 10
【样例输出】
27
【样例说明】
只更改第 1 , 2 , 4 , 5 , 7 , 8 1, 2, 4, 5, 7, 8 1,2,4,5,7,8 个数,需要花费代价 1 + 2 + 4 + 5 + 7 + 8 = 27 1 + 2 + 4 + 5 + 7 + 8 = 27 1+2+4+5+7+8=27。
【评测用例规模与约定】
对于 20 % 20\% 20% 的评测用例, n ≤ 1000 n ≤ 1000 n≤1000;
对于所有评测用例, n ≤ 100000 , 0 m) ans += abs[i].b; System.out.println(ans); } StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); int nextInt() { try { in.nextToken(); } catch (IOException e) { e.printStackTrace(); } return (int) in.nval; } }
试题 E: 填充
时间限制: 3.0 s 3.0\mathrm s 3.0s 内存限制: 512.0 M B 512.0\mathrm{MB} 512.0MB 本题总分: 15 15 15 分
【问题描述】
有一个长度为 n n n 的 01 01 01 串,其中有一些位置标记为 ? ? ?,这些位置上可以任意填充 0 0 0 或者 1 1 1,请问如何填充这些位置使得这个 01 01 01 串中出现互不重叠的 00 00 00 和 11 11 11 子串最多,输出子串个数。
【输入格式】
输入一行包含一个字符串。
【输出格式】
输出一行包含一个整数表示答案。
【样例输入】
1110?0
【样例输出】
2
【样例说明】
如果在问号处填 0 0 0,则最多出现一个 00 00 00 和一个 11 : 111000 11:111000 11:111000。
【评测用例规模与约定】
对于所有评测用例, 1 ≤ n ≤ 1000000 1 ≤ n ≤ 1000000 1≤n≤1000000。
贪心
?怎么还是贪心
如果以01相接的地方为断点,将01串拆分开来,如1110?0拆分成111、0?0,则显然第二段中的问号应填0,于是只需考虑若干问号存在01之间的情况,如果若干问号的左侧段长为奇数,则考虑将一个问号变为左侧段对应的值,使总答案加一,然后将所有问号变为右侧段对应的值,若剩余问号为奇数则这个数字除二向下取整是雷打不动的,而多余的一个变为左侧对答案无贡献,所以直接变右,这么模拟着递推过来就行。
实现时连续的问号同时当做0、1来看待,然后找到子串后清空累计即可。
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String ...args) { new Main().run(); } void run() { try (BufferedReader in = new BufferedReader(new InputStreamReader(System.in))) { String s = in.readLine(); int ans = 0, cnt0 = 0, cnt1 = 0; for (int i = 0; i 0) ++cnt0; else if (cnt1 > 0) ++cnt1; else { ++cnt0; ++cnt1; } } if (cnt0 == 2 || cnt1 == 2) { cnt0 = cnt1 = 0; ++ans; } } System.out.println(ans); } catch (IOException e) { e.printStackTrace(); } } }
试题 F: 棋盘
时间限制: 3.0 s 3.0\mathrm s 3.0s 内存限制: 512.0 M B 512.0\mathrm{MB} 512.0MB 本题总分: 15 15 15 分
【问题描述】
小蓝拥有 n × n n × n n×n 大小的棋盘,一开始棋盘上全都是白子。小蓝进行了 m m m 次操作,每次操作会将棋盘上某个范围内的所有棋子的颜色取反 (也就是白色棋子变为黑色,黑色棋子变为白色)。请输出所有操作做完后棋盘上每个棋子的颜色。
【输入格式】
输入的第一行包含两个整数 n , m n, m n,m,用一个空格分隔,表示棋盘大小与操作数。
接下来 m m m 行每行包含四个整数 x 1 , y 1 , x 2 , y 2 x_1, y_1, x_2, y_2 x1,y1,x2,y2,相邻整数之间使用一个空格分隔,表示将在 x 1 x_1 x1 至 x 2 x_2 x2 行和 y 1 y_1 y1 至 y 2 y_2 y2 列中的棋子颜色取反。
【输出格式】
输出 n n n 行,每行 n n n 个 0 0 0 或 1 1 1 表示该位置棋子的颜色。如果是白色则输出 0 0 0,否则输出 1 1 1。
【样例输入】
3 3 1 1 2 2 2 2 3 3 1 1 3 3
【样例输出】
001 010 100
【评测用例规模与约定】
对于 30 % 30\% 30% 的评测用例, n m ≤ 500 n m ≤ 500 nm≤500;
对于所有评测用例, 1 ≤ n , m ≤ 2000 , 1 ≤ x 1 ≤ x 2 ≤ n , 1 ≤ y 1 ≤ y 2 ≤ m 1 ≤ n, m ≤ 2000,1 ≤ x_1 ≤ x_2 ≤ n,1 ≤ y_1 ≤ y_2 ≤ m 1≤n,m≤2000,1≤x1≤x2≤n,1≤y1≤y2≤m。
二维差分,捞的不谈。
import java.io.PrintWriter; import java.io.StreamTokenizer; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.IOException; public class Main { public static void main(String ...args) { new Main().run(); } boolean[][] board = new boolean[2002][2002]; void run() { PrintWriter out = new PrintWriter(System.out); int n = nextInt(), m = nextInt(); for (int i = 0; i
还没有评论,来说两句吧...