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组题目如何

蓝桥杯第十二届真题解析

2021第十二届蓝桥杯省赛JAVA B组 题目+答案(复现赛)

2021年软件类第十二届蓝桥杯 省赛 python组 A-E题解