【不爱施肥的小布】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
import java.math.BigInteger;
import java.util.stream.Stream;
class Main {
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
int m = in.nextInt();
int n = in.nextInt();
in.nextLine();
Integer[] fields = Arrays.stream(in.nextLine().split(" ")).map(Integer::parseInt).toArray(Integer[]::new);
// 最少天数小于果林大小可直接返回-1
if (n<m) {
System.out.println(-1);
return;
}
// 最少天数等于果林大小可直接返回max(fields)
if (n==m) {
System.out.println((int) Collections.max(Arrays.asList(fields)));
return;
}
//排序找到最大最小值
Arrays.sort(fields);
int left = 0;
int right = fields[fields.length - 1];
int result = -1;
while (left +1 < right) {
//取中间位置的值作为效能k,这里的k取得是其在数组中的index
int k = (int) Math.ceil((double)(left + right) / 2);
int res = cal(k, fields);
if (res - n > 0) {
left = k;
} else {
result = k;
right = k;
}
}
System.out.println(result);
}
//判断效能为k时,所需总天数
public static int cal(int k, Integer[] fields) {
int days = 0;
for (int i=0;i<fields.length;i++) {
days += Math.ceil(fields[i] / (double)k);
}
return days;
}
}
【组装新的数组】-200
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
import java.math.BigInteger;
import java.util.stream.Stream;
class Main {
public static int m;
public static int min_num;
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
Integer[] nums = Arrays.stream(in.nextLine().split(" ")).map(Integer::parseInt).toArray(Integer[]::new);
m = in.nextInt();
//排序找到最小值
Arrays.sort(nums);
min_num = nums[0];
System.out.println(dfs(nums, 0, 0, 0));
}
public static int dfs(Integer[] nums, int index, int sum, int count) {
if (sum > m) {
return count;
}
//满足边界条件+1
if (sum <= m && m - min_num < sum) {
return count + 1;
}
for (int i = index; i < nums.length; i++) {
count = dfs(nums, i, sum + nums[i], count);
}
return count;
}
}
【快速开租建站】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
import java.math.BigInteger;
import java.util.stream.Stream;
class Main {
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
int taskNum = in.nextInt();
int relationsNum = in.nextInt();
int[][] relation_ids = new int[relationsNum][2];
for (int i = 0; i < relationsNum; i++) {
relation_ids[i][0] = in.nextInt();
relation_ids[i][1] = in.nextInt();
}
// 每个任务的前置依赖任务个数,也就是拓扑排序中的入度
int[] upstream = new int[taskNum];
// 每个任务的下游任务, 也就是拓扑排序中的出度
List<List<Integer>> downstream =new ArrayList<List<Integer>>(taskNum);
for (int i=0;i<taskNum;i++) {
downstream.add(new ArrayList<>());
}
//初始化入度、出度
for (int[] relation_id : relation_ids) {
downstream.get(relation_id[0]).add(relation_id[1]);
upstream[relation_id[1]]+=1;
}
//队列中保存当前入度为0 的任务id
LinkedList<Integer[]> queue = new LinkedList<>();
int result = 1;
for (int i = 0; i < taskNum; i++) {
//将所有入度为零的任务入队, 默认耗时为1
if (upstream[i] == 0) {
queue.add(new Integer[] {i, result});
}
}
while (queue.size() > 0) {
Integer[] current_task = queue.removeFirst();
int task = current_task[0];
int time = current_task[1];
for (Integer downstream_task : downstream.get(task)) {
// 当前任务的入度减小到0时,放入queue中
if (--upstream[downstream_task] == 0) {
result = time + 1;
queue.add(new Integer[] {downstream_task, result});
}
}
}
System.out.println(result);
}
}
【统计友好度最大值】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
import java.math.BigInteger;
import java.util.stream.Stream;
class Main {
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
Integer[] seats = Arrays.stream(in.nextLine().split(" ")).map(Integer::parseInt).toArray(Integer[]::new);
ArrayList<Integer> left_result_arr = new ArrayList<Integer>();
Integer left_result = 0;
for (int i = 0; i < seats.length; i++) {
if (seats[i] == 0) {
left_result_arr.add(left_result);
left_result = 0;
} else if (seats[i] == 1) {
left_result +=1;
} else {
left_result =0;
}
}
ArrayList<Integer> right_result_arr = new ArrayList<Integer>();
Integer right_result = 0;
for (int i = seats.length - 1; i >= 0; i--) {
if (seats[i] == 0) {
right_result_arr.add(right_result);
right_result = 0;
} else if (seats[i] == 1) {
right_result +=1;
} else {
right_result =0;
}
}
int result = 0;
for (int i = 0; i < left_result_arr.size(); i++) {
result = Math.max(result, left_result_arr.get(i) + right_result_arr.get(left_result_arr.size()-i-1));
}
System.out.println(result);
}
}
【荒地建设电站 / 区域发电量统计】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
//处理输入
Scanner in=new Scanner(System.in);
List<Integer> params =Arrays.stream(in.nextLine().split(" "))
.map(Integer::parseInt)
.collect(Collectors.toList());
int n = params.get(0);
int m = params.get(1);
int c = params.get(2);
int k = params.get(3);
int[][] matrix = new int [n][m];
for (int i=0;i<n;i++) {
String[] num_strs =in.nextLine().split(" ");
for (int j=0;j<m;j++) {
matrix[i][j] = Integer.parseInt(num_strs[j]);
}
}
System.out.println(get_area_count(matrix, k, c));
}
public static int get_area_count(int[][] mat, int threshold, int c) {
int n = mat.length;
int m = mat[0].length;
int[][] s = new int [n+1][m+1];
//1、生成前缀和子矩阵
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= m; ++j) {
//s[i][j]表示以[i,j]作为矩阵最右下角的最大矩阵的前缀和
//解释:以点[i,j]作为作为最右下角的最大矩阵的前缀和需要加上点[i-1,j]和点[i,j-1]的前缀和,然而会重复多加一个点[i-1][j-1]的前缀和,所以要减一个
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + mat[i - 1][j - 1];
}
}
int ans = 0;
//2、遍历前缀和矩阵,获得边长等于c的矩阵
for (int i = c; i <= n; ++i) {
for (int j = c; j <= m; ++j) {
//重点理解:减去点[i-c][j]和点[i][j-c]的矩阵前缀和,剩下来的为一个边长为c正方形,注意点[i-c][j-c]减了两次,需要加一个回来
if (s[i][j] - s[i - c][j] - s[i][j - c] + s[i - c][j - c] >= threshold)
ans += 1;
}
}
return ans;
}
}
【最大连续文件之和 / 区块链文件转储系统 】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
import java.math.BigInteger;
import java.util.stream.Stream;
class Main {
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
int M =in.nextInt();
in.nextLine();
Integer[] F = Arrays.stream(in.nextLine().split(" ")).map(Integer::parseInt).toArray(Integer[]::new);
// 窗口左右边界
int left = 0, right = 0;
//窗口和
int window_sum = 0;
//最大窗口和
int window_max = 0;
while (right < F.length) {
int temp = window_sum + F[right];
// 窗口内总和大了,sum减去左边界,左端边界+1
if (temp > M) {
window_sum -= F[left];
left += 1;
}
// 窗口内总和小了,右边界+1,sum加上右边界
else if (temp < M) {
window_sum += F[right];
window_max = Math.max(window_sum, window_max);
right += 1;
}
// 窗口内总和==M,直接return
else {
System.out.println(M);
return;
}
}
System.out.println(window_max);
}
}
【发现新词的数量 /新词挖掘】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
import java.math.BigInteger;
import java.util.stream.Stream;
class Main {
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
String content = in.nextLine();
String word = in.nextLine();
System.out.println(contin(content, word));
}
public static int contin(String content, String word){
if(content.length() < word.length())
return 0;
if(word.length() == 0)
return 0;
HashMap<Character, Integer> content_map = new HashMap<Character, Integer>();
HashMap<Character, Integer> word_map = new HashMap<Character, Integer>();
//先统计出word中的字符组成
for (int i=0;i<word.length();i++)
word_map.put(word.toCharArray()[i], word_map.getOrDefault(word.toCharArray()[i], 0) + 1);
char[] content_arr = content.toCharArray();
int word_char_kind = word_map.size();
int right = 0;
int content_child_char_kind = 0;
int result = 0;
while(right < content.length()){
if(right >= word.length()){
int left = right - word.length();
if (word_map.containsKey(content_arr[left]) && word_map.get(content_arr[left]) == content_map.get(content_arr[left]))
content_child_char_kind -=1 ;
content_map.put(content_arr[left], content_map.getOrDefault(content_arr[left], 0) - 1);
}
content_map.put(content_arr[right], content_map.getOrDefault(content_arr[right], 0) + 1);
if (word_map.containsKey(content_arr[right]) && word_map.get(content_arr[right]) == content_map.get(content_arr[right]))
content_child_char_kind+=1;
right+=1;
if (content_child_char_kind == word_char_kind) {
result += 1;
}
}
return result;
}
}
【最接最大输出功率的设备 /查找充电设备组合】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
import java.math.BigInteger;
import java.util.stream.Stream;
class Main {
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
int n = in.nextInt();
in.nextLine();
Integer[] p = Arrays.stream(in.nextLine().split(" ")).map(Integer::parseInt).toArray(Integer[]::new);
int p_max = in.nextInt();
//dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。
int[][] dp = new int[n + 1][p_max + 1];
// 初始化, i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。
for (int j = p_max; j >= p[0]; j--) {
dp[0][j] = dp[0][j - p[0]] + p[0];
}
for (int i = 1; i < n; i++) { // 遍历物品
for (int j = 0; j <= p_max; j++) { // 遍历背包容量
// 背包容量为j,如果物品i的体积,此时dp[i][j]就是dp[i - 1][j]
if (j < p[i]) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - p[i]] + p[i]);
}
}
}
System.out.println(dp[n-1][p_max]);
}
}
【计算是否能达到公司 /上班之路】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
class Main {
private static final int[][] directions = {{0, 1, 1}, {0, -1, 2}, {1, 0, 3}, {-1, 0, 4}};
private static int t, c, n, m;
private static String[][] matrix;
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
t = in.nextInt();
c = in.nextInt();
n = in.nextInt();
m = in.nextInt();
matrix = new String[n][m];
for (int i = 0; i < n; i++) {
matrix[i] = in.next().split("");
}
//遍历矩阵,找到起点
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
boolean[][] visited = new boolean[m][n];
if ("S".equals(matrix[i][j])) {
if (dfs(visited, i, j, 0, 0, 0)) {
System.out.println("YES");
return;
} else {
System.out.println("NO");
return;
}
}
}
}
System.out.println("NO");
return;
}
public static boolean dfs(boolean[][] visited, int x, int y, int ut, int uc, int last_direct) {
// 找到目的地
if ("T".equals(matrix[x][y])) {
return true;
}
//表示当前点已走过
visited[x][y] = true;
// 有四个方向选择走下一步
for (int[] direction : directions) {
int direct = direction[2];
int new_x = x + direction[0];
int new_y = y + direction[1];
// 转向+破壁标记
boolean turn_flag = false;
boolean break_flag = false;
// 越界 + 是否当前点已访问判断
if (new_x >= 0 && new_x < n && new_y >= 0 && new_y < m && !visited[new_x][new_y]) {
//转向+破壁判断
if (last_direct != 0 && last_direct != direct) {
// 转向次数已用尽
if (ut + 1 > t) {
continue;
}
turn_flag = true;
}
if ("*".equals(matrix[new_x][new_y])) {
// 破壁次数已用尽
if (uc + 1 > c) {
continue;
}
break_flag = true;
}
// 可到达目的地T, 返回true
if (dfs(visited, new_x, new_y, ut + (turn_flag ? 1 : 0), uc + (break_flag ? 1 : 0), direct)) {
return true;
}
}
}
return false;
}
}
【简单的解压缩算法】【2023 Q1 | 200分】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
class Main {
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
//防止最后一个字符是数字
String input_str = in.nextLine() + " ";
LinkedList<String> stack = new LinkedList<>();
// bracket_pos 保存的是所有花括号出现的位置
LinkedList<Integer> bracket_pos = new LinkedList<>();
// 保存数字的字符串
String number_str = "";
for (int i = 0; i < input_str.length(); i++) {
char c = input_str.charAt(i);
//数字
if (c >= '0' && c <= '9') {
number_str += c;
continue;
}
if (number_str.length() > 0) {
int repeat_count = Integer.parseInt(number_str);
number_str = "";
// 若此时栈顶是 } 字符, 将对应的字母重复repeat_count次
if ("}".equals(stack.getLast())) {
//获取上一个 { 的位置
int pos = bracket_pos.removeLast();
//删除左右{}
stack.remove(pos);
stack.removeLast();
// 重复{}之间的字母
repeat_operation(stack, pos, repeat_count);
} else {
//不是 } 字符, 简单重复栈顶字符对应次即可
repeat_operation(stack, stack.size() - 1, repeat_count);
}
}
// { 字符
if (c == '{') {
bracket_pos.add(stack.size());
}
// 其他字符 (字母 + })
stack.add(c + "");
}
// 输出
System.out.println(stack.stream().collect(Collectors.joining()));
}
// 重复{}内的字母, 并重新入栈
public static void repeat_operation(LinkedList<String> stack, int pos, int repeat_count) {
int count = stack.size() - pos;
// temp_stack用于存储弹栈数据
String[] temp_stack = new String[count];
while (count >= 1) {
count -= 1;
temp_stack[count] = stack.removeLast();
}
String temp_str = String.join("", temp_stack);
StringBuilder result = new StringBuilder();
//重复repeat_count次
for (int i = 0; i < repeat_count; i++) {
result.append(temp_str);
}
stack.add(result.toString());
}
}
【修建高铁最优成本 /最优高铁城市修建方案】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
class Main {
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int pair_count_1 = in.nextInt();
int pair_count_2 = in.nextInt();
// 可建设高铁的两城市
int[][] city_pair_1 = new int[pair_count_1][3];
for (int i = 0; i < pair_count_1; i++) {
city_pair_1[i][0] = in.nextInt();
city_pair_1[i][1] = in.nextInt();
city_pair_1[i][2] = in.nextInt();
}
// 必建高铁的两城市
int[][] city_pair_2 = new int[pair_count_2][2];
for (int i = 0; i < pair_count_2; i++) {
city_pair_2[i][0] = in.nextInt();
city_pair_2[i][1] = in.nextInt();
}
UF uf = new UF(n);
// key为修建高铁的两个城市,value为费用
HashMap<String, Integer> city_map = new HashMap<>();
for (int[] city_pair : city_pair_1) {
int city1 = city_pair[0], city2 = city_pair[1];
city_map.put(city1 < city2 ? city1 + "-" + city2 : city2 + "-" + city1, city_pair[2]);
}
int result = 0;
// 先计算必建高铁情况下的费用
for (int[] city_pair : city_pair_2) {
int city1 = city_pair[0], city2 = city_pair[1];
result += city_map.get(city1 < city2 ? city1 + "-" + city2 : city2 + "-" + city1);
// 纳入并查集
uf.union(city1, city2);
}
System.out.println(result);
// 已经满足所有城市通车,直接返回
if (uf.count == 1) {
System.out.println(result);
return;
}
// 按修建费用排序
Arrays.sort(city_pair_1, (a, b) -> a[2] - b[2]);
for (int[] city_pair : city_pair_1) {
int city1 = city_pair[0], city2 = city_pair[1];
// 判断两城市是否相连
if (uf.item[city1] != uf.item[city2]) {
uf.union(city1, city2);
// 若可以合入,则将对应的建造成本计入result
result += city_pair[2];
}
if (uf.count == 1) {
break;
}
}
// count>1代表有的城市无法通车
if (uf.count > 1) {
System.out.println(-1);
return;
}
System.out.println(result);
}
}
// 并查集
class UF {
int[] item;
int count;
public UF(int n) {
item = new int[n + 1];
count = n;
for (int i = 0; i < n; i++) item[i] = i;
}
public int find(int x) {
if (x != item[x]) {
return (item[x] = find(item[x]));
}
return x;
}
public void union(int x, int y) {
int x_item = find(x);
int y_item = find(y);
if (x_item != y_item) {
item[y_item] = x_item;
count--;
}
}
}