11-200【羊、狼、农夫过河】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
class Main {
public static int min_times;
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
//转为数组
List<Integer> nums =Arrays.stream(in.nextLine().split(" "))
.map(Integer::parseInt)
.collect(Collectors.toList());
int M = nums.get(0);
int N = nums.get(1);
int X = nums.get(2);
min_times = (M+N)*X;
// 表示已运输到对岸的羊、狼个数
int m_temp=0;
int n_temp=0;
transport(M, N, X, m_temp, n_temp, 0);
if(min_times==(M+N)*X){
System.out.println(0);
}else{
System.out.println(min_times);
}
}
// m0, n0 分别表示剩余的羊、狼个数, x为船容量
// m1, n1 分别表示运输到对岸的羊、狼个数,times为次数
public static int transport(int m0, int n0, int x, int m1, int n1,int times) {
//若可以一次性运走,结束了,注意等于号。。。
if(x>=m0+n0){
if(times+1<min_times){
min_times=times+1;
}
return times+1;
}
//尝试运一部分狼一部分羊
//要上船的羊数量不可以超过岸上数量、也不可以超过船的容量
for(int i=0;i<=m0&&i<=x;i++){
//要上船的狼的数量不可以超过岸上数量、也不可以超过船装了羊后的剩余的容量
for(int j=0;j<=n0&&i+j<=x;j++){
//不可以不运
if(i+j==0){
continue;
}
//船离岸后,原来这岸,要么没有羊,要么羊比狼多,才可以运;对岸也要检查,不考虑回程带动物
if((m0-i==0||m0-i>n0-j)&&(m1+i==0||m1+i>n1+j)){
//运一次
int result=transport(m0-i,n0-j,x,m1+i,n1+j,times+1);
//如果获取了结果,和minTime比较,但是不结束,继续检查
if(result<min_times&&result!=0){
min_times=result;
}
}
}
}
//没有方案了。。返回0
return 0;
}
}
贪心
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);
//转为数组
List<Integer> nums =Arrays.stream(in.nextLine().split(" "))
.map(Integer::parseInt)
.collect(Collectors.toList());
int M = nums.get(0);
int N = nums.get(1);
int X = nums.get(2);
// 分支1.1
if (M <= N) {
System.out.println(0);
return;
}
// 分支2.1
if (N < X) {
// 分支2.1.1
if (N < Math.floor((double)X / 2)) {
M -= X - N;
}
System.out.println((int)Math.ceil((double)M / X) + 1);
return;
}
// 分支2.2
N -= X - 1;
int N_opposite = X - 1;
M -= X;
int M_opposite = X;
// 第一轮已经两次了
int result = 2;
// 后续运输的初始规则(船上的羊多于狼1个)
int sheep_boat = (int)Math.ceil((double)X / 2) + (X % 2 == 0 ? 1 : 0);
int wolf_boat = X - sheep_boat;
while (M > 0) {
// 分支2.2.1
if (M - sheep_boat > N - wolf_boat || (M == sheep_boat && N == wolf_boat)) {
M -= sheep_boat;
M_opposite += sheep_boat;
N -= wolf_boat;
N_opposite += wolf_boat;
result++;
// 分支2.2.2
} else {
int tmp = M_opposite - N_opposite - 1;
if (tmp == 0) {
System.out.println(0);
return;
}
N -= tmp;
N_opposite += tmp;
result++;
}
}
System.out.println(result);
}
}
12【完美走位】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
import java.util.function.Function;
class Main {
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
String input_str = in.nextLine();
//预设值
Map<Character,Integer> char_count = new HashMap<Character,Integer>();
//遍历字符串
for(int i=0; i<input_str.length(); i++) {
char key = input_str.charAt(i);
if(char_count.get(key) == null) {
char_count.put(key, 1);
} else{
char_count.put(key,char_count.get(key)+1);
}
}
//遍历WASD,防止输入没有这三个字符
for(int i=0; i<"WASD".length(); i++) {
char key = "WASD".charAt(i);
if(char_count.get(key) == null) {
char_count.put(key, 0);
}
}
// 特殊情况
if (char_count.get('W') == char_count.get('A') &&
char_count.get('W') == char_count.get('S') &&
char_count.get('W') == char_count.get('D')) {
System.out.println(0);
return;
}
// 左右区间位置
int left = 0;
int right = 0;
int length = 0;
// 替换的最小长度
int res = input_str.length();
// 出现次数最多的字母
int max_char_num = 0;
// 可替换字母个数, 随着指针移动,如果free_char_num 大于0且能被4整除,当前范围满足条件,左指针右移一格,否则右指针右移
int free_char_num = 0;
char_count.put(input_str.charAt(0), char_count.get(input_str.charAt(0)) - 1);
while (true) {
max_char_num = Math.max(Math.max((Math.max(char_count.get('W'), char_count.get('S'))), char_count.get('A')), char_count.get('D'));
length = right - left + 1;
free_char_num = length - ((max_char_num - char_count.get('W')) + (max_char_num - char_count.get('S')) + (max_char_num - char_count.get('A')) + (max_char_num - char_count.get('D')));
if (free_char_num >= 0 && free_char_num % 4 == 0){
if(length<res) {
res = length;
}
char_count.put(input_str.charAt(left), char_count.get(input_str.charAt(left)) + 1);
left++;
} else {
right++;
char_count.put(input_str.charAt(right), char_count.get(input_str.charAt(right)) - 1);
}
if (right >= input_str.length()-1)// 越界即结束
break;
}
System.out.println(res);
}
}
13【过滤组合字符串】
import java.util.Scanner;
import java.util.*;
class Main {
public static ArrayList<String> res_str_list;
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
String num_str = in.nextLine();
String block_str = in.nextLine();
//预设值
HashMap<Character, String> num_char_map = new HashMap<Character, String>();
num_char_map.put('0',"abc");
num_char_map.put('1',"def");
num_char_map.put('2',"ghi");
num_char_map.put('3',"jkl");
num_char_map.put('4',"mno");
num_char_map.put('5',"pqr");
num_char_map.put('6',"st");
num_char_map.put('7',"uv");
num_char_map.put('8',"wx");
num_char_map.put('9',"yz");
res_str_list = new ArrayList<String>();
ArrayList<Character> char_list_temp = new ArrayList<Character>();
dfs(num_str, char_list_temp, 0, num_char_map);
int result_count = res_str_list.size();
for (String x : res_str_list) {
// 过滤
if (x.contains(block_str)) {
result_count -= 1;
}
}
System.out.println(result_count);
}
// 递归求出所有可能的排列组合
public static void dfs(String num_str, ArrayList<Character> list, int index, HashMap<Character, String> num_char_map) {
if(index == num_str.length()) {
String temp_str = "";
for (int i=0;i<list.size();i++) {
temp_str = temp_str + list.get(i);
}
res_str_list.add(temp_str);
return;
}
for (char single_char : num_char_map.get(num_str.toCharArray()[index]).toCharArray()) {
list.add(single_char);
dfs(num_str, list, index+1, num_char_map);
list.remove(list.size() - 1);
}
}
}
14【模拟商场优惠打折】
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 m = params.get(0);
int n = params.get(1);
int k = params.get(2);
int x = Integer.parseInt(in.nextLine());
while (in.hasNext()) {
int price = Integer.parseInt(in.nextLine());
int[][] result = new int[4][2];
//System.out.println(m + "\t" + n + "\t" + price);
result[0] = mode_a(price, m, n);
//System.out.println(m + "\t" + n + "\t" + price);
result[1] = mode_b(price, m, n);
//System.out.println(m + "\t" + n + "\t" + price);
result[2] = mode_c(price, m, k);
//System.out.println(m + "\t" + n + "\t" + price);
result[3] = mode_d(price, n, k);
//for (int i = 0; i < result.length; i++) {
// for (int j = 0; j < result[i].length; j++) {
// System.out.print(result[i][j] + "\t");
// }
// System.out.println("");
//}
//System.out.println("===========================================");
//按照价格降序,用券数降序排序
Arrays.sort(result, (int[] a, int[] b) -> {
if (a[0] != b[0]) {
// 第一个数不相等 第一个数降序
return a[0] - b[0];
} else {
// 第一个数相等 第二个数降序
return a[1] - b[1];
}
});
System.out.print(result[0][0]);
System.out.print(" ");
System.out.println(result[0][1]);
}
}
//先满减后打折
public static int[] mode_a(int price, int m, int n) {
int count = 0;
while(m > 0) {
if (price < 100) {
break;
}
price -= (price/100 * 10);
count += 1;
m--;
}
price *= 0.92;
count += 1;
int a[] = {price, count};
return a;
}
//先打折后满减
public static int[] mode_b(int price, int m, int n) {
int count = 0;
price *= 0.92;
count += 1;
while(m > 0) {
if (price <100) {
break;
}
price -= (price/100 * 10);
count += 1;
m--;
}
int a[] = {price, count};
return a;
}
//先满减后无门槛
public static int[] mode_c(int price, int m, int k) {
int count = 0;
while(m > 0) {
if (price <100) {
break;
}
price -= (price/100 * 10);
count += 1;
m--;
}
for (int i=0;i<k;i++) {
price -= 5;
count += 1;
if (price <0) {
break;
}
}
int a[] = {price, count};
return a;
}
//先打折后无门槛
public static int[] mode_d(int price, int n, int k) {
int count = 0;
price *= 0.92;
count += 1;
for (int i=0;i<k;i++) {
price -= 5;
count += 1;
if (price < 0) {
break;
}
}
int a[] = {price, count};
return a;
}
}
15【探索地块建立】
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;
}
}
16【日志首次上报最多积分】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static int max_machine=0;
public static void main(String[] args) {
//处理输入
Scanner in=new Scanner(System.in);
List<Integer> logs =Arrays.stream(in.nextLine().split(" "))
.map(Integer::parseInt)
.collect(Collectors.toList());
//加分
int[] plus_score = new int[logs.size()];
plus_score[0] = logs.get(0);
// 减分
int[] minus_score = new int[logs.size()];
minus_score[0] = 0;
int[] result = new int[logs.size()];
result[0] = logs.get(0);
for (int i = 1; i < logs.size(); i++) {
plus_score[i] = Math.min(100, plus_score[i - 1] + logs.get(i));
minus_score[i] = minus_score[i - 1] + plus_score[i - 1];
result[i] = plus_score[i] - minus_score[i];
if (plus_score[i] >= 100) {
break;
}
}
int max_score = 0; // 最大值
for (int item : result) {
if (item > max_score) {
max_score = item;
}
}
System.out.println(max_score);
}
}
17-处理器问题/ 高性能AI处理器】
import java.util.Scanner;
import java.util.*;
import java.util.stream.Stream;
import java.util.stream.Collectors;
class Main {
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
Integer[] cores = Arrays.stream(in.nextLine().split("[\\[\\]\\,\\s]"))
.filter(str -> !"".equals(str))
.map(Integer::parseInt)
.toArray(Integer[]::new);
int target = in.nextInt();
//初始化两个链路剩余可用的处理器
ArrayList<Integer> processors_1 = new ArrayList<>();
ArrayList<Integer> processors_2 = new ArrayList<>();
Arrays.sort(cores, (a, b) -> a - b);
for (Integer core : cores) {
if (core < 4) {
processors_1.add(core);
} else {
processors_2.add(core);
}
}
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
int length_1 = processors_1.size();
int length_2 = processors_2.size();
switch (target) {
case 1:
if (length_1 == 1 || length_2 == 1) {
if (length_1 == 1) dfs(processors_1, 0, 1, new ArrayList<>(), result);
if (length_2 == 1) dfs(processors_2, 0, 1, new ArrayList<>(), result);
} else if (length_1 == 3 || length_2 == 3) {
if (length_1 == 3) dfs(processors_1, 0, 1, new ArrayList<>(), result);
if (length_2 == 3) dfs(processors_2, 0, 1, new ArrayList<>(), result);
} else if (length_1 == 2 || length_2 == 2) {
if (length_1 == 2) dfs(processors_1, 0, 1, new ArrayList<>(), result);
if (length_2 == 2) dfs(processors_2, 0, 1, new ArrayList<>(), result);
} else if (length_1 == 4 || length_2 == 4) {
if (length_1 == 4) dfs(processors_1, 0, 1, new ArrayList<>(), result);
if (length_2 == 4) dfs(processors_2, 0, 1, new ArrayList<>(), result);
}
break;
case 2:
if (length_1 == 2 || length_2 == 2) {
if (length_1 == 2) dfs(processors_1, 0, 2, new ArrayList<>(), result);
if (length_2 == 2) dfs(processors_2, 0, 2, new ArrayList<>(), result);
} else if (length_1 == 4 || length_2 == 4) {
if (length_1 == 4) dfs(processors_1, 0, 2, new ArrayList<>(), result);
if (length_2 == 4) dfs(processors_2, 0, 2, new ArrayList<>(), result);
} else if (length_1 == 3 || length_2 == 3) {
if (length_1 == 3) dfs(processors_1, 0, 2, new ArrayList<>(), result);
if (length_2 == 3) dfs(processors_2, 0, 2, new ArrayList<>(), result);
}
break;
case 4:
if (length_1 == 4 || length_2 == 4) {
if (length_1 == 4) result.add(processors_1);
if (length_2 == 4) result.add(processors_2);
}
break;
case 8:
if (length_1 == 4 && length_2 == 4) {
result.add(
Stream.concat(processors_1.stream(), processors_2.stream())
.collect(Collectors.toCollection(ArrayList<Integer>::new)));
}
break;
}
System.out.println(result.toString());
}
public static void dfs(ArrayList<Integer> cores,int index,int level,ArrayList<Integer> path,ArrayList<ArrayList<Integer>> res) {
if (path.size() == level) {
res.add((ArrayList<Integer>) path.clone());
return;
}
for (int i = index; i < cores.size(); i++) {
path.add(cores.get(i));
// 逐个往后找合适的组合
dfs(cores, i + 1, level, path, res);
path.remove(path.size() - 1);
}
}
}
18-【打印机队列】
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);
int count = in.nextInt();
in.nextLine();
//5台打印机的打印清单
//使用匿名内部类创建Comparator实现类,重写compare方法
TreeSet<ArrayList<Integer>> print_machine= new TreeSet<>(new Comparator<ArrayList<Integer>>() {
@Override
public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
int result = o2.get(0) - o1.get(0);
if (result == 0) {
return o1.get(1) - o2.get(1);
}
return result;
}
});
List<TreeSet<ArrayList<Integer>>> print_machines = new ArrayList<TreeSet<ArrayList<Integer>>>();
//不想改序号了,按题目要求是从1开始编号的,但是多一个也无妨
for (int i=0;i<=5;i++) {
print_machines.add(new TreeSet<>(new Comparator<ArrayList<Integer>>() {
@Override
public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
int result = o2.get(0) - o1.get(0);
if (result == 0) {
return o1.get(1) - o2.get(1);
}
return result;
}
}));
}
int file_count = 0;
for (int i=0;i< count;i++) {
String[] operation_info = in.nextLine().split(" ");
if (operation_info[0].equals("IN")) {
file_count += 1;
ArrayList<Integer> temp = new ArrayList<Integer>();
temp.add(Integer.parseInt(operation_info[2]));
temp.add(file_count);
//放入文件
print_machines.get(Integer.parseInt(operation_info[1])).add(temp);
} else {
//打印
if (print_machines.get(Integer.parseInt(operation_info[1])).size() > 0) {
System.out.println(print_machines.get(Integer.parseInt(operation_info[1])).first().get(1));
print_machines.get(Integer.parseInt(operation_info[1])).pollFirst();
} else {
System.out.println("NULL");
}
}
}
}
}
19-【积木最远距离】
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);
int count = in.nextInt();
HashMap<Integer, List<Integer>> blocks = new HashMap<Integer, List<Integer>>();
for (int i = 0;i<count;i++) {
int num = in.nextInt();
if (blocks.containsKey(num)) {
List<Integer> block_pos = blocks.get(num);
block_pos.add(i);
blocks.put(num, block_pos);
} else {
List<Integer> block_pos = new ArrayList<Integer>();
block_pos.add(i);
blocks.put(num, block_pos);
}
}
int max_distance = -1;
for (Map.Entry<Integer, List<Integer>> x : blocks.entrySet()) {
if (x.getValue().size() > 1) {
max_distance = Math.max(max_distance, Collections.max(x.getValue()) - Collections.min(x.getValue()));
}
}
System.out.println(max_distance);
}
}
20-【最大平分数组】
import java.util.Scanner;
import java.util.*;
class Main {
public static void main(String[] args) {
// 处理输入
Scanner in = new Scanner(System.in);
String param_str = in.nextLine();
int count = Integer.valueOf(param_str);
//构造输入数据结构,并求和
int[] nums = new int[count];
String num_str = in.nextLine();
int sum = 0;
String[] num_list = num_str.split(" ");
for (int i=0;i<count;i++) {
nums[i] = Integer.valueOf(num_list[i]);
sum += Integer.valueOf(num_list[i]);
}
// 最大可以等分为m个子数组
for (int i=count;i>0;i--) {
//从最大的可能行开始,满足条件即为为最小的情况
if (canPartitionKSubsets(nums, i, sum)) {
System.out.println(i);
break;
}
}
}
public static boolean canPartitionKSubsets(int[] nums, int k, int all) {
if (all % k != 0) {
return false;
}
int per = all / k;
Arrays.sort(nums);
int n = nums.length;
if (nums[n - 1] > per) {
return false;
}
boolean[] dp = new boolean[1 << n];
int[] curSum = new int[1 << n];
dp[0] = true;
for (int i = 0; i < 1 << n; i++) {
if (!dp[i]) {
continue;
}
for (int j = 0; j < n; j++) {
if (curSum[i] + nums[j] > per) {
break;
}
if (((i >> j) & 1) == 0) {
int next = i | (1 << j);
if (!dp[next]) {
curSum[next] = (curSum[i] + nums[j]) % per;
dp[next] = true;
}
}
}
}
return dp[(1 << n) - 1];
}
}