第十二届蓝桥杯 Java B 组省赛填空题解析
第一题
【问题描述】
已知大写字母 A A A 的 A S C I I ASCII ASCII 码值为 65 65 65, 那么大写字母 L L L 的 A S C I I ASCII ASCII 码值为多少?
【思路】
签到题
【代码】
public class Q1 {
public static void main(String[] args) {
System.out.println((int) ('A'));
}
}
【答案】
76
第二题
【问题描述】

【思路】
用数组记录每个数字使用的次数,当拼到 i i i 时的某一位数字不够用,则答案为 i − 1 i - 1 i−1
【代码】
import java.util.Arrays;
public class Q2 {
static int[] a = new int[10];
static boolean check(int num) {
while (num > 0) {
int x = num % 10;
if (--a[x] < 0)
return false;
num /= 10;
}
return true;
}
public static void main(String[] args) {
Arrays.fill(a, 2021);
int i = 0;
while (true) {
if (!check(++i))
break;
}
System.out.println(i - 1);
}
}
【答案】
3181
第三题
【问题描述】

【思路】
我们可以根据任意两个点确定一条直线
1)当直线不平行于 x x x 轴和 y y y 轴时,可以表示为 y = k x + b y=kx+b y=kx+b 的形式
设两点为 p 1 ( x 1 , y 1 ) , p 2 ( x 2 , y 2 ) p1(x1,y1),p2(x2,y2) p1(x1,y1),p2(x2,y2) x 1 ≠ x 2 且 y 1 ≠ y 2 x1 \neq x2 且 y1\neq y2 x1=x2且y1=y2 则有
y − y 1 = ( ( y 2 − y 1 ) / ( x 2 − x 1 ) ) ∗ ( x − x 1 ) y-y1=((y2-y1)/(x2-x1))*(x-x1) y−y1=((y2−y1)/(x2−x1))∗(x−x1)
令 y 2 − y 1 = d y , x 2 − x 1 = d x y2-y1=dy,x2-x1=dx y2−y1=dy,x2−x1=dx
k = d y / d x k=dy/dx k=dy/dx
b = ( y 1 ∗ d x − x 1 ∗ d y ) / d x b=(y1*dx-x1*dy)/dx b=(y1∗dx−x1∗dy)/dx
将得到的 k k k 和 b b b 存入 s e t set set 中
2)当直线平行于 x x x 轴和 y y y 轴时,只需要加上 x x x 轴和 y y y 轴上的点数
【代码】
1)分数表示,由于浮点数存在精度问题,可以使用分数表示 k k k 和 b b b
import java.util.HashSet;
import java.util.Set;
public class Q3 {
static int n = 20;
static int m = 21;
static Set<String> set = new HashSet<>();
static int gcd(int x, int y) {
return y == 0 ? x : gcd(y, x % y);
}
public static void main(String[] args) {
for (int x1 = 0; x1 < n; x1++) {
for (int y1 = 0; y1 < m; y1++) {
for (int x2 = 0; x2 < n; x2++) {
for (int y2 = 0; y2 < m; y2++) {
if (x1 == x2 || y1 == y2) continue;
int dy = y2 - y1;
int dx = x2 - x1;
int g1 = gcd(dx, dy);
// 需要将 dy 和 dx 约分
String k = (dy / g1) + "/" + (dx / g1);
int t = y1 * dx - x1 * dy;
int g2 = gcd(t, dx);
String b = (t / g2) + "/" + (dx / g2);
set.add(k + "," + b);
}
}
}
}
// 别忘了加上平行于 x 轴和 y 轴的直线
System.out.println(set.size() + n + m);
}
}
- 浮点数表示
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class Q3Beta {
static int n = 20;
static int m = 21;
// 精度
static double d = 0.000001;
static Set<Line> set = new HashSet<>();
static class Line {
double k;
double b;
public Line(double k, double b) {
this.k = k;
this.b = b;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Line line = (Line) o;
return Math.abs(line.k - k) < d &&
Math.abs(line.b - b) < d;
}
@Override
public int hashCode() {
return Objects.hash((int)k, (int)b);
}
}
public static void main(String[] args) {
for (int x1 = 0; x1 < n; x1++) {
for (int y1 = 0; y1 < m; y1++) {
for (int x2 = 0; x2 < n; x2++) {
for (int y2 = 0; y2 < m; y2++) {
if (x1 == x2 || y1 == y2) continue;
double dy = y2 - y1;
double dx = x2 - x1;
double k = dy / dx;
double b = (y1 * dx - x1 * dy) / dx;
set.add(new Line(k, b));
}
}
}
}
System.out.println(set.size() + n + m);
}
}
【答案】
40257
第四题
【问题描述】

【思路】
若长宽高为 A B C ABC ABC 形,则有 6 6 6 种方案,即 A B C , A C B , B A C , B C A , C A B , C B A ABC,ACB,BAC,BCA,CAB,CBA ABC,ACB,BAC,BCA,CAB,CBA
若为 A A B AAB AAB 形, 则有 3 3 3 种方案,即 A A B , A B A , B A A AAB,ABA,BAA AAB,ABA,BAA
若为 A A A AAA AAA 形,则只有 1 1 1 种方案
由此可知,
当为 A B C ABC ABC 形时,设 L < W < H L<W<H L<W<H
则 L L L 最大时小于 2021041820210418 3 = 126432.415 \sqrt[3]{2021041820210418}=126432.415 32021041820210418=126432.415, 暴力计算是可以接受的
【代码】
public class Q4 {
static long n = 2021041820210418L;
static int ans;
public static void main(String[] args) {
// AAB 和 AAA 形式
for (long i = 1; i * i <= n; i++) {
if (n % (i * i) != 0) continue;
long j = n / (i * i);
if (j == i)
ans++; // AAA 形式只有一种排列方式
else
ans += 3; // AAB 形式有三种排列方式
}
// ABC 形式,i < j < k
for (long i = 1; i * i * i < n; i++) {
if (n % i != 0) continue;
for (long j = i + 1; j * i < n; j++) {
// 若 k = n / (i * j) < j, 则退出循环
if (n / (i * j) < j) break;
if (n % (i * j) == 0)
ans += 6; // ABC 形式有六种排列方式
}
}
System.out.println(ans);
}
}
【答案】
2430
第五题
【问题描述】

【思路】
板子题, d i j k s t r a dijkstra dijkstra 算法
【代码】
import java.util.Arrays;
import java.util.PriorityQueue;
public class Q5 {
static int[] d = new int[2100];
static boolean[] vis = new boolean[2100];
static PriorityQueue<Integer> heap = new PriorityQueue<>((o1, o2) -> d[o1] - d[o2]);
static int gcd(int x, int y) {
return y == 0 ? x : gcd(y, x % y);
}
static int lcm(int x, int y) {
return x * y / gcd(x, y);
}
static void dijkstra() {
Arrays.fill(d, Integer.MAX_VALUE);
d[1] = 0;
vis[1] = true;
for (int i = 2; i <= 22; i++) {
d[i] = lcm(1, i);
heap.add(i);
}
while (!heap.isEmpty()) {
int v = heap.poll();
if (vis[v]) continue;
vis[v] = true;
if (v == 2021) break;
for (int i = Math.max(1, v - 21); i <= Math.min(2021, v + 21); i++) {
if (!vis[i]) {
d[i] = Math.min(d[i], d[v] + lcm(v, i));
heap.add(i);
}
}
}
System.out.println(d[2021]);
}
public static void main(String[] args) {
dijkstra();
}
}
【答案】
10266837