ブルーブリッジカップの31日間のスプリントの最後から2日目[java]

数日前にインターネットの試験の準備をしていて、それから数日間クーリングしました。今日は少し生意気ですが、やめられません。やめた
のでしびれます。数日前に何日なのかわからない明後日テストを受けます2日目までのカウントダウンです

馬の探索

画像-20220407130102079

トピックリンク:https ://www.luogu.com.cn/problem/P1443

この質問も典型的なbfsトラバーサルですが、馬のグリッドは8になり、通常のグリッドと変わりません。

もう1つの問題は、出力形式を実行するのが簡単ではないことです。C言語を習得していない場合は、出力形式にとどまると推定されます。これはとんでもないことです。

package daily;

import java.util.Deque;
import java.util.LinkedList;
import java.util.Scanner;

/**
 * https://www.luogu.com.cn/problem/P1443
 * 
 * @author Jia
 *
 */
public class day4_7_1 {
    
    
	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int x = sc.nextInt();
		int y = sc.nextInt();
		sc.close();

		// 下一步可以走的8个格子
		int[] nextCol = {
    
     1, 2, 2, 1, -1, -2, -2, -1 };
		int[] nextRow = {
    
     2, 1, -1, -2, -2, -1, 1, 2 };

		// 初始化棋盘
		int[][] board = new int[n][m];
		for (int i = 0; i < board.length; i++) {
    
    
			for (int j = 0; j < board[0].length; j++) {
    
    
				board[i][j] = -1;
			}
		}
		board[x - 1][y - 1] = 0;

		// 初始化队列
		Deque<BoardNode> queue = new LinkedList<>();
		queue.addLast(new BoardNode(x - 1, y - 1));

		// bfs遍历所有节点,第一次走到的一定是最近的,所以只需要判断走到的节点是不是没有走到就可以
		while (!queue.isEmpty()) {
    
    
			BoardNode node = queue.removeFirst();
			for (int i = 0; i < nextRow.length; i++) {
    
    
				int newRow = nextRow[i] + node.row;
				int newCol = nextCol[i] + node.col;
				if (newRow >= 0 && newRow < n && newCol >= 0 && newCol < m && board[newRow][newCol] == -1) {
    
    
					board[newRow][newCol] = board[node.row][node.col] + 1;
					queue.add(new BoardNode(newRow, newCol));
				}
			}
		}

		// 输出
		for (int i = 0; i < board.length; i++) {
    
    
			for (int j = 0; j < board[0].length; j++) {
    
    
				// %-5d表示输出的是整数并且向右对其5个单位
				System.out.printf("%-5d", board[i][j]);
			}
			System.out.println();
		}
	}
}

class BoardNode {
    
    
	int row;
	int col;

	public BoardNode(int row, int col) {
    
    
		super();
		this.row = row;
		this.col = col;
	}
}

ロープを切れ

画像-20220407132151013

トピックリンク:https ://www.luogu.com.cn/problem/P1577

この質問を読んだ後、最初の感覚は答えを見つけるためにトラバースすることですが、0から最大値まで開始すると非常に遅くなるため、二分法を考え、二分法を使用して答えをリストし、次に、答えが条件を満たしているかどうかを常に確認します。満たされている場合は、最後の左端と右端が一致するまで検索を続けます

ここでも処理を行いました。タイトルには小数点以下2桁しか必要ないため、すべての値に100を掛けて、読み込み時に保存し、最終的に出力するときに再度処理できます。いくつかの非常に深刻な問題を避けてください。法外な精度の問題

ここでは、31行目にmid === 0を追加してループから抜け出しましたが、その理由はよくわかりません。初めてユースケースを作成したときは、それを理解できませんでした。その後、確認したところ、誰かが私がこれを追加する必要があると言いました.0で除算するのを避けるために

package daily;

import java.util.Scanner;

/**
 * https://www.luogu.com.cn/problem/P1577
 * 
 * @author Jia
 *
 */
public class day4_7_2 {
    
    
	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int K = sc.nextInt();
		int[] arr = new int[N];
		int max = 0;
		// 处理出入数据
		for (int i = 0; i < arr.length; i++) {
    
    
			arr[i] = (int) (sc.nextFloat() * 100);
			max = Math.max(max, arr[i]);
		}
		sc.close();

		int left = 0;
		int right = max;
		int ans = 0;
		// 二分寻找答案
		while (left <= right) {
    
    
			int mid = (right - left) / 2 + left;
			if (mid == 0) {
    
    
				break;
			}
			if (check(arr, mid, K)) {
    
    
				left = mid + 1;
				ans = mid;
			} else {
    
    
				right = mid - 1;
			}
		}
		System.out.printf("%.2f", (double) ans / 100);
	}

	/**
	 * 判断当前长度是否可以切出来
	 * 
	 * @param arr
	 * @param mid
	 * @param k
	 * @return
	 */
	private static boolean check(int[] arr, int mid, int k) {
    
    
		int ans = 0;
		for (int i = 0; i < arr.length; i++) {
    
    
			ans += arr[i] / mid;
		}
		return ans >= k;
	}
}

ミサイル迎撃

画像-20220407132805754

トピックリンク:https ://www.luogu.com.cn/problem/P1020

この質問は少し混乱し、バックパックの問題のように感じ、株の売買の問題のように感じます。私には理解できません。

おすすめ

転載: blog.csdn.net/qq_46311811/article/details/124014378