Java实现蓝桥杯第十二届2021年JavaB组真题
Posted Johnny*
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java实现蓝桥杯第十二届2021年JavaB组真题相关的知识,希望对你有一定的参考价值。
花已经枯了 浇再多的水也没用
C 直线
【题目描述】
【思路】
区域中的点两两组合,根据斜截式计算出每条直线的k和b。
难点在于对于 <k,b>怎么不重不漏地统计数量。
这里想到用 Map<Double, Set>,注意k、b可能为小数。相同的k映射到 同一个Set中,用Set判去重复的b。
package 第十二届;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* @author JohnnyLin
* @version Creation Time:2021年5月9日 上午8:52:55
* 类说明
*/
public class _C直线 {
// static int N = 2, M = 3;
static int N = 20, M = 21;
static Map<Double, Set<Double>> map = new HashMap<>();
//计算斜率
public static double getK(int x1, int y1, int x2, int y2) {
return (double) (y1 - y2) /(x1 - x2) ;
}
public static void main(String[] args) {
for(int i = 0; i < N; i ++) {
for(int j = 0; j < M; j ++) {
//(i, j) --> (x, y)
for(int x = 0; x < N; x ++) {
if( i == x) continue;
for(int y = 0; y < M; y ++) {
if( y == j) continue;
double k = getK(i, j, x, y);
double b = j - k * i;
if( !map.containsKey(k) ) {
System.out.println(k);
Set<Double> set = new HashSet<>();
set.add(b);
map.put(k, set);
}else {
Set<Double> set = map.get(k);
set.add(b);
}
}
}
}
}
int ans = 0;
for(Entry<Double, Set<Double>> entry: map.entrySet()) {
ans += entry.getValue().size();
}
//47753
System.out.println( ans + N + M);
}
}
package 第十二届;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
class Line{
double k, b;
public Line(double kk, double bb){
this.k = kk;
this.b = bb;
}
//重写equals方法: 比较k和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 Double.compare(line.k, k) == 0 &&
Double.compare(line.b, b) == 0;
}
@Override
public int hashCode() {
//使用包装类
Double kk = this.k;
Double bb = this.b;
int result = 1;
result = 31 * result + (kk == null ? 0 : kk.hashCode());
result = 31 * result + (bb == null ? 0 : bb.hashCode());
return result;
}
}
public class _C直线2 {
static int N = 20, M = 21;
static Set<Line> set = new HashSet<>();
//计算斜率
public static double getK(int x1, int y1, int x2, int y2) {
return (double) (y1 - y2) /(x1 - x2) ;
}
public static void main(String[] args) {
for(int i = 0; i < N; i ++) {
for(int j = 0; j < M; j ++) {
//(i, j) --> (x, y)
for(int x = 0; x < N; x ++) {
if( i == x) continue;
for(int y = 0; y < M; y ++) {
if( y == j) continue;
double k = getK(i, j, x, y);
double b = j - k * i;
set.add(new Line(k, b) );
}
}
}
}
// 47753
System.out.println(set.size() + N + M);
}
}
看了一下其他大佬给的答案,我写的不对,据说是精度问题(四舍五入),所以结果多了。正确答案是:40257
正解
【思路】
需要通过Math.ads(k1-k2)>1e-8 || Math.ads(b1-b2)>1e-8 |来判断不同的直线。
排序
正确答案是:40257
package 第十二届.right;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
class Line implements Comparable<Line>{
double k, b;
public Line(double kk, double bb){
this.k = kk;
this.b = bb;
}
@Override
public int compareTo(Line o) {
if( Double.compare(this.k, o.k) == 0 ) return Double.compare(this.b, o.b);
return Double.compare(this.k, o.k);
}
}
public class _C直线3 {
static int N = 20, M = 21;
// static int N = 2, M = 3;
static Line[] q = new Line[1000000];
static double esp = 10E-8;
//计算斜率
public static double getK(int x1, int y1, int x2, int y2) {
return (double) (y1 - y2) /(x1 - x2) ;
}
public static void main(String[] args) {
int t = 0;
for(int i = 0; i < N; i ++) {
for(int j = 0; j < M; j ++) {
//(i, j) --> (x, y)
for(int x = 0; x < N; x ++) {
if( i == x) continue;
for(int y = 0; y < M; y ++) {
if( y == j) continue;
double k = getK(i, j, x, y);
double b = j - k * i;
q[t ++] = new Line(k, b);
}
}
}
}
//排序
Arrays.sort(q, 0, t);
int res = 1; //k :{1,1,2,2,3,3} {1,2,3}
for( int i = 1; i < t; i ++)
if( Math.abs(q[i].k - q[i - 1].k ) > esp || Math.abs(q[i].b - q[i - 1].b ) > esp)
res ++;
System.out.println(res + N + M);
}
}
D 货物摆放
【思路】
三个数a、b、c,乘积是n。n的约数中选三个,乘积是n的组合有多少。
当时写的时候觉得很难,觉得非dp写不出来。看了y总的解答后, 原来暴力也可以,是自己太菜了,多刷题、多刷题、多刷题。
重要事情讲三遍。
答案: 2430
package 第十二届;
import java.util.ArrayList;
import java.util.List;
/**
* @author JohnnyLin
* @version Creation Time:2021年5月9日 下午12:59:44
*/
public class _D货物摆放 {
static long N = 2021041820210418L;
static List<Long> f = new ArrayList<>();
public static void main(String[] args) {
/**
* N = 4时, i = 1 2
* N/i 4 2
*/
for(long i = 1; i * i <= N; i ++) {
if( N % i== 0) {
f.add(i);
//
if( N / i != i) f.add(N / i);
}
}
long ans = 0;
for(long a: f)
for(long b: f)
for(long c : f) {
if( a * b * c == N) ans++;
}
System.out.println(ans);
}
}
E路径
【思路】
spaf
package 第十二届;
import java.util.Arrays;
/**
* @author JohnnyLin
* @version Creation Time:2021年5月9日 下午1:43:36
*/
public class _E路径 {
static int N = 2200, M = N *50;//N: 点数 M:边数
static int h[] = new int [N];
static int e[] = new int [M];
static int w[] = new int [M];
static int ne[] = new int [M];
static int idx, n;
static int q[] = new int[N];
static int dist[] = new int[N];
static boolean st[] = new boolean[N];
static int INF = 0x3f3f3f3f;
public static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
public static void add(int a, int b, int c) {//添加一条边a -> b ,边的权重为c
e[idx] = b;
w[idx] = c;
ne[idx]= h[a];
h[a] = idx ++;
}
//求1号点到n号点的最短路径
public static void spfa() {
int hh = 0, tt = 0;
Arrays.fill(dist, INF);
dist[1] = 0;
q[tt ++] = 1;
st[1] = true;
while( hh != tt) {
int t = q[hh ++];
if( hh == N) hh = 0;
st[t] = false;
for(int i = h[t]; i != -1; i = ne[i]) {
int j = e[i];
if( dist[j] > dist[t] + w[i]) {
dist[j] = dist[t] + w[i];
if (!st[j]) // 如果队列中已存在j,则不需要将j重复插入
{
q[tt ++ ] = j;
if (tt == N) tt = 0;
st[j] = true;
}
}
}
}
}
public static void main(String[] args) {
n = 2021;
Arrays.fill(h, - 1);
for(int i = 1; i <= n; i ++) {
for(int j = Math.max(1, i - 21); j <= Math.min(i + 21, n); j ++) {
//(i,j)节点
int d = gcd(i, j);
add(i, j, i * j / d);
}
}
spfa();
System.out.println(dist[n]);
}
}
时间显示
【题目描述】
【思路】
时间换算 注意 1s = 1000ms即可
import java.util.Scanner;
public class Main{
public static void main(String args[]){
Scanner reader = new Scanner(System.in);
long time = reader.nextLong();
//1618708103123
//24*60 * 60s
// 1s = 1000ms
long fact = 3600 * 1000;
long f = 24 以上是关于Java实现蓝桥杯第十二届2021年JavaB组真题的主要内容,如果未能解决你的问题,请参考以下文章
2021年软件类第十二届蓝桥杯第二场省赛 python组 A-E题解
2023年第十四届蓝桥杯将至来看看第十二届蓝桥杯javaB组题目如何