前几天一直在准备计网考试,然后咕咕了几天,今天写感觉有点生了,还是不能停的呀,麻了
因为前面停了几天也不知道该多少天,后天就考试了,索性就倒数第二天了
马的遍历
题目链接:https://www.luogu.com.cn/problem/P1443
这个题也是一个典型的bfs遍历,只是马走的格子变成了8个,和平常做的没什么区别
另外一个难点就是输出格式不好搞hhh,要不是曾经学过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;
}
}
切绳子
题目链接:https://www.luogu.com.cn/problem/P1577
这个题看完之后第一感觉就是遍历找答案,但是如果是从0开始遍历到最大值会很慢,所以很自然就会想到二分法,使用二分列举答案,然后不断检查这个答案是否满足条件,如果满足则继续查找,直到最后左右端点重合
我这里还进行了一次处理,由于题目中要求只保留两位小数,所以在读入的时候把所有的值乘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;
}
}
导弹拦截
题目链接:https://www.luogu.com.cn/problem/P1020
这个题感觉有点迷,有点像背包问题,又有点像力扣上一个买卖股票的问题,想不明白。。