无脑
无脑
检查是否存在满足条件的数字组合
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int count = Integer.parseInt(in.nextLine());
String[] split = in.nextLine().split(" ");
int[] arr = new int[count];
for (int i = 0; i < count; i++) {
arr[i] = Integer.parseInt(split[i]);
}
Arrays.sort(arr);
reverse(arr);
for (int i = 0; i < arr.length; i++) {
int A = arr[i];
for (int j = i + 1; j < arr.length; j++) {
int B = arr[j];
for (int k = j + 1; k < arr.length; k++) {
int C = arr[k];
if (A == B + 2 * C){
System.out.println(A + " " + B + " " + C);
return;
}
if (A == C + 2 * B){
System.out.println(A + " " + C + " " + B);
return;
}
}
}
}
System.out.println(0);
}
public static void reverse(int[] arr){
int l = 0;
int r = arr.length - 1;
while (l < r){
int temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
l++;
r--;
}
}
}
高矮个子排队
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
for (int i = 0; i < s.length(); i++) {
String substring = s.substring(i, i + 1);
if (substring.matches("[^0-9 ]+")){
System.out.println("[]");
return;
}
}
String[] split = s.split(" ");
int[] arr = new int[split.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.parseInt(split[i]);
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (i % 2 == 0){ // 高
if (i + 1 < arr.length && arr[i] < arr[i + 1]){
swap(arr, i, i + 1);
}
}else{ // 矮
if (i + 1 < arr.length && arr[i] > arr[i + 1]){
swap(arr, i, i + 1);
}
}
}
for (int i : arr) {
sb.append(i + " ");
}
System.out.println(sb.toString().trim());
}
public static void swap(int[] arr, int l, int r){
int temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
}
}
最小面试官数【】
第一个球,放第一个桶。
第二个球,先尝试放第一个桶,首先检查桶中球个数是否已达到m,若已达到,则不能放入,继续尝试放入下一个桶,若未达到,则将球和桶最上面的球比较,即看面试时间是否有交集,如果有交集,则不能放入,继续尝试放入下一个桶,如果没有交集,则可以放入。
按照上面逻辑,放入所有球。
然后把空桶排除掉,剩下还有几个桶,就需要几个面试官。
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int inJointCount = -1;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
List<People> list = new ArrayList<>();
int interviewCount = in.nextInt();
int count = in.nextInt();
for (int i = 0; i < count; i++) {
list.add(new People(in.nextInt(), in.nextInt()));
}
Collections.sort(list, (o1, o2) -> {
return o1.end - o2.end; // 按照结束时间升序
});
int[] arr = new int[count];
int[] end = new int[count]; // 标记每个桶的结束时间
for (int i = 0; i < list.size(); i++) {
People people = list.get(i);
for (int j = 0; j < arr.length; j++) {
if (arr[j] == 0){
arr[j]++;
end[j] = people.end;
break;
}else {
if (arr[j] < interviewCount){
if (people.start >= end[j]){
arr[j]++;
end[j] = people.end;
break;
}
}
}
}
}
int res = 0;
for (int i : arr) {
if (i != 0){
res++;
}else {
break;
}
}
System.out.println(res);
}
}
class People{
int start;
int end;
public People(int start, int end) {
this.start = start;
this.end = end;
}
}
靠谱的车【求余、余数大于 4 的话要 - 1, res = Math.pow(9, i) * 余数】
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int res = 0;
int i = 0;
while (N != 0){
int d = N % 10;
N /= 10;
if (d > 4){
d -= 1;
}
res += Math.pow(9, i) * d;
i++;
}
System.out.println(res);
}
}
食堂供餐【二分法:库存要满足当前的消费】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = Integer.parseInt(in.nextLine());
int M = Integer.parseInt(in.nextLine()); // 库存
String[] split = in.nextLine().split(" ");
int[] arr = new int[N];
int max = -1;
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.parseInt(split[i]);
max = Math.max(max, arr[i]);
}
int res = 0;
int min = 0;
while (min <= max){
int mid = min + (max - min) / 2;
if (isValid(arr, M, mid)){
res = mid;
max = mid - 1;
}else {
min = mid + 1;
}
}
System.out.println(res);
}
public static boolean isValid(int[] arr, int M, int day){
for (int i = 0; i < arr.length; i++) {
if (M < arr[i]){ // 库存不满足当天消费
return false;
}else {
M = M - arr[i] + day; // 更新库存!!!
}
}
return true;
}
}
组装最大可靠性设备【二分法:先利用TreeSet保存所有可能性的结果,然后转成数组,利用二分法】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] split = in.nextLine().split(" ");
int S = Integer.parseInt(split[0]);
int N = Integer.parseInt(split[1]); // N 种类型
int count = Integer.parseInt(in.nextLine());
TreeSet<Integer> set = new TreeSet<>(); // 收集可靠性
List<List<Equip>> list = new ArrayList<>();
for (int i = 0; i < N; i++) {
list.add(new ArrayList<>());
}
for (int i = 0; i < count; i++) {
int type = in.nextInt();
int reliability = in.nextInt();
int price = in.nextInt();
set.add(reliability);
list.get(type).add(new Equip(type, price, reliability));
}
Integer[] arr = set.stream().toArray(Integer[]::new);
for (List<Equip> equips : list) { // 对每种类型按照可靠性升序!!!
Collections.sort(equips, (o1, o2) -> o1.reliability - o2.reliability);
}
int l = 0;
int r = arr.length - 1;
int res = -1;
while (l <= r){
int mid = l + (r - l) / 2;
if (isValid(list, arr[mid], S)){
res = arr[mid];
l = mid + 1;
}else {
r = mid - 1;
}
}
System.out.println(res);
}
public static boolean isValid(List<List<Equip>> list, int max, int s){
int sum = 0;
for (List<Equip> equips : list) {
int index = binarySearch(equips, max);
if (index < 0){
index = -index - 1;
}
if (index == equips.size()){
return false;
}
sum += equips.get(index).price;
}
return sum <= s;
}
public static int binarySearch(List<Equip> equips, int max){
List<Integer> list = new ArrayList<>();
for (Equip equip : equips) {
list.add(equip.reliability);
}
return Collections.binarySearch(list, max);
}
}
class Equip {
int type;
int price;
int reliability;
public Equip(int type, int price, int reliability) {
this.type = type;
this.price = price;
this.reliability = reliability;
}
}
最小交换次数【统计所有数字中小于 target 的作为滑窗长度,然后统计每个滑窗中 >= target的个数】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] split = in.nextLine().split(" ");
int[] arr = new int[split.length];
int target = in.nextInt();
int count = 0; // 最多交换次数
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.parseInt(split[i]);
if (arr[i] < target){
count++;
}
}
int MoreTarget = 0;
for (int i = 0; i < count; i++) {
if (arr[i] >= target){
MoreTarget++;
}
}
int res = MoreTarget;
for (int i = count; i < arr.length; i++) {
int left = arr[i - count];
if (left >= target){
MoreTarget--;
}
int now = arr[i];
if (now >= target){
MoreTarget++;
}
res = Math.min(res, MoreTarget);
}
System.out.println(res);
}
}
勾股数元组【互质】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int M = in.nextInt();
List<Integer> list = new ArrayList<>();
for (int i = N; i <= M; i++) {
list.add(i * i);
}
boolean flag = false; // 是否有解
for (int i = 0; i < list.size(); i++) {
Integer A = list.get(i);
for (int j = i + 1; j < list.size(); j++) {
Integer B = list.get(j);
if (list.contains(A + B)) {
int a = (int) Math.sqrt(A);
int b = (int) Math.sqrt(B);
int c = (int) Math.sqrt(A + B);
if (isValid(a, b) && isValid(b, c)) {
flag = true;
System.out.println(a + " " + b + " " + c);
}
}
}
}
if (!flag){
System.out.println("NA");
}
}
public static int gcd(int a, int b){
if (a == 0){
return b;
}
int min = Math.min(a, b);
int max = Math.max(a, b);
max = max % min;
return gcd(max, min);
}
public static boolean isValid(int a, int b){
return gcd(a, b) == 1;
}
}
素数之积【是否为质数】:能被当前数或者当前数 + 2 整除!!!
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for (int i = 2; i < n; i++) {
if (n % i == 0){
if (isPrime(i) && isPrime(n / i)){
System.out.println(i + " " + n / i);
}else {
System.out.println("-1 -1");
}
break;
}
}
}
public static boolean isPrime(int n){
if (n == 1){
return false;
}
if (n <= 3){
return true;
}
if (n % 2 == 0 || n % 3 == 0){
return false;
}
for (int i = 5; i < Math.sqrt(n); i += 6) {
if (n % i == 0 || n % (i + 2) == 0){
return false;
}
}
return true;
}
}
数字序列比较大小【田忌赛马】
先排序:找出最快和最慢的马
田忌 min > 齐王 min:最慢的马非必输,我们应该继续寻找
田忌 min <= 齐王 min:最慢的马必输,当作对子去抵消齐王 max
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int count = Integer.parseInt(in.nextLine());
int[] arr1 = new int[count];
int[] arr2 = new int[count];
int res = 0;
for (int i = 0; i < count; i++) {
arr1[i] = in.nextInt();
}
for (int i = 0; i < count; i++) {
arr2[i] = in.nextInt();
}
Arrays.sort(arr1);
Arrays.sort(arr2);
int l1 = 0;
int r1 = count - 1;
int l2 = 0;
int r2 = count - 1;
while (l1 <= r1){
if (arr1[r1] > arr2[r2]){ // 赢
res++;
r1--;
r2--;
}else if (arr1[r1] < arr2[r2]){ // 输
res--;
l1++;
r2--;
}else { // 最快的平手
// 开始比较最慢的
if (arr1[l1] <= arr2[l2]){ // 必输 或者 无法创造价值
if (arr1[l1] < arr2[r2]){
res--;
}
l1++;
r2--;
}else { // 赢
res++;
l1++;
l2++;
}
}
}
System.out.println(res);
}
}
227. 机器人走迷宫【DFS:由于一定可以到达终点,所以终点初始化为2,这样才能正常影响它附近的位置】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int row;
static int col;
static int[][] arr;
static int unReachable;
static int trap;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
row = in.nextInt();
col = in.nextInt();
arr = new int[row][col];
arr[row - 1][col - 1] = 2;
int count = in.nextInt();
for (int i = 0; i < count; i++) {
arr[in.nextInt()][in.nextInt()] = 1;
}
backtracking(0, 0);
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (arr[i][j] == 0){
unReachable++;
}
if (arr[i][j] == -1){
trap++;
}
}
}
System.out.println(trap + " " + unReachable);
}
public static boolean backtracking(int i, int j){
if (i == row || j == col){ // 越界
return false;
}
if (arr[i][j] == 1){ // 碰壁
return false;
}
if (arr[i][j] == -1){ // 不可达
return false;
}
if (arr[i][j] == 2){ // 访问过
return true;
}
if (arr[i][j] == 0) {
boolean right = backtracking(i, j + 1); // 向右
boolean down = backtracking(i + 1, j); // 向下
if (right || down) { // 当前可以走
arr[i][j] = 2;
} else { // 都走不了
arr[i][j] = -1;
}
}
return arr[i][j] == 2;
}
}
KMP
最小循环子数组【看 count % (count - next[count - 1]) == 0?】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int count = Integer.parseInt(in.nextLine());
int[] arr = new int[count];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
arr[i] = in.nextInt();
sb.append(arr[i]);
}
int[] temp = KMP(sb.toString());
int m = temp[temp.length - 1];
int res = count % (count - m) == 0? count - m:count;
StringBuilder ans = new StringBuilder();
for (int i = 0; i < res; i++) {
ans.append(sb.charAt(i) + " ");
}
System.out.println(ans.toString().trim());
}
public static int[] KMP(String str){
int[] next = new int[str.length()];
next[0] = 0;
for (int i = 1, j = 0; i < str.length(); i++) {
while (j > 0 && str.charAt(i) != str.charAt(j)){
j = next[j - 1];
}
if (str.charAt(i) == str.charAt(j)){
next[i] = ++j;
}
}
return next;
}
}
寻找相同子串【KMP】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String target = in.nextLine();
String s = in.nextLine();
int[] next = getNext(s);
int res = find(next, s, target);
res += 1; // 下标从 1 开始
if (res == 0){
System.out.println("No");
return;
}
System.out.println(res);
}
// s:模式串
public static int find(int[] next, String s, String target){
int index = -1;
for (int i = 0, j = 0; i < target.length(); i++) {
while (j > 0 && target.charAt(i) != s.charAt(j)){
j = next[j - 1];
}
if (target.charAt(i) == s.charAt(j)){
j++;
}
if (j == s.length()){
index = i - s.length() + 1;
break;
}
}
return index;
}
public static int[] getNext(String s){
int[] next = new int[s.length()];
next[0] = 0;
for (int i = 1,j = 0; i < s.length(); i++) {
while (j > 0 && s.charAt(i) != s.charAt(j)){
j = next[j - 1];
}
if (s.charAt(i) == s.charAt(j)){
next[i] = ++j;
}
}
return next;
}
}
补种未成活胡杨【构建未成活数组arr】
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int M = in.nextInt();
int[] arr = new int[M];
for (int i = 0; i < arr.length; i++) {
arr[i] = in.nextInt();
}
int k = in.nextInt();
System.out.println(getCount(N, M, arr, k));
}
public static int getCount(int N, int M, int[] arr, int k){
if (M == k){
return N; // 全部填充
}
int max = 0;
for (int i = 0; i <= M - k; i++) {
if (i == 0){ // 第一个
max = Math.max(max, arr[i + k] - 1); // 后方 arr[i + k] 【后方的空缺处 - 1】
}else if (i == M - k){ // 最后一个
max = Math.max(max, N - arr[i - 1]); // 当前位置:arr[i - 1]
}else {
max = Math.max(max, arr[i + k] - arr[i - 1] - 1);
}
}
return max;
}
}
215. 最大矩阵和【截取二维数组 + DP】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int row;
static int col;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
row = in.nextInt();
col = in.nextInt();
int[][] arr = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
arr[i][j] = in.nextInt();
}
}
System.out.println(getResult(arr));
}
public static int getResult(int[][] arr){
List<Integer> list = new ArrayList<>();
for (int i = 0; i < row; i++) {
list.add(getMax(arr[i])); // 单行
for (int j = i + 2; j <= row; j++) {
list.add(getMax(Zip(Arrays.copyOfRange(arr, i, j)))); // 多行
}
}
Collections.sort(list, (o1, o2) -> o2 - o1);
return list.get(0);
}
public static int getMax(int[] nums){
int[] dp = new int[nums.length + 1];
int res = Integer.MIN_VALUE;
for (int i = 1; i < dp.length; i++) {
// 看前一个状态是否有效? + 当前状态
dp[i] = Math.max(0, dp[i - 1]) + nums[i - 1];
res = Math.max(res, dp[i]);
}
return res;
}
public static int[] Zip(int[][] arr){
int row = arr.length;
int col = arr[0].length;
int[] zip = new int[col];
for (int i = 0; i < col; i++) { // 列
for (int j = 0; j < row; j++) { // 行
zip[i] += arr[j][i];
}
}
return zip;
}
}
构成正方形的数量
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int count = in.nextInt();
int res = 0;
if (count < 4){
System.out.println(0);
return;
}
List<Point> list = new ArrayList<>();
for (int i = 0; i < count; i++) {
list.add(new Point(in.nextInt(), in.nextInt()));
}
for (int i = 0; i < list.size(); i++) {
Point point1 = list.get(i);
for (int j = i + 1; j < list.size(); j++) {
Point point2 = list.get(j);
int x3 = point1.x - (point1.y - point2.y);
int y3 = point1.y + (point1.x - point2.x);
int x4 = point2.x - (point1.y - point2.y);
int y4 = point2.y + (point1.x - point2.x);
int x5 = point1.x + (point1.y - point2.y);
int y5 = point1.y - (point1.x - point2.x);
int x6 = point2.x + (point1.y - point2.y);
int y6 = point2.y - (point1.x - point2.x);
Point point3 = new Point(x3, y3);
Point point4 = new Point(x4, y4);
Point point5 = new Point(x5, y5);
Point point6 = new Point(x6, y6);
if (list.contains(point3) && list.contains(point4)){
res++;
}
if (list.contains(point5) && list.contains(point6)){
res++;
}
}
}
System.out.println(res / 4);
}
}
class Point{
int x;
int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return x == point.x &&
y == point.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
}
编码能力提升计划【二分法:min = 0,max = sum - max】
如果我们在一天内写完所有题目,那么要花费的时间是sum(time),另外,我们可以在这一天申请看一题答案,免去一题的做题时间,此时最优策略是,看耗时最多的那题,即一天最多耗时 T = sum(time) - max(time)
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] split = in.nextLine().split(",");
int count = split.length;
int[] arr = new int[split.length];
int max = 0;
int sum = 0;
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.parseInt(split[i]);
max = Math.max(max, arr[i]);
sum += arr[i];
}
int day = in.nextInt();
if (count <= day){
System.out.println(0);
return;
}
max = sum - max;
int min = 0;
int res = Integer.MAX_VALUE;
while (min <= max){
int mid = min + (max - min) / 2;
if (isValid(arr, mid, day)){
res = Math.min(res, mid);
max = mid - 1;
}else {
min = mid + 1;
}
}
System.out.println(res);
}
public static boolean isValid(int[] arr, int time, int day){
int sum = 1;
int temp = time;
int max = 0;
boolean flag = true; // 当天是否可以跳过
for (int i = 0; i < arr.length; i++) {
max = Math.max(max, arr[i]);
time -= arr[i];
if (time < 0){
if (flag){
time += max; // 因为跳过了最大的,那么得把营养给补回来
flag = false;
}else { // 不能申请帮助,只能放到明天来做
sum++;
time = temp;
max = 0;
i--;
flag = true;
}
}
}
return sum <= day;
}
}
找终点
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int res = Integer.MAX_VALUE;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] split = in.nextLine().split(" ");
int[] arr = new int[split.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.parseInt(split[i]);
}
int firstStep = arr.length / 2;
// 1. 第一步必须从第一元素开始,且1<=第一步的步长<len/2;(len为数组的长度,需要自行解析
for (int i = 1; i <= firstStep - 1 ; i++) {
Go(arr, i);
}
if (res == Integer.MAX_VALUE){
System.out.println(-1);
return;
}
System.out.println(res);
}
public static void Go(int[] arr, int index){
int sum = 1;
while (index + arr[index] < arr.length){
index += arr[index];
sum++;
}
if (index == arr.length - 1){ // 能否陪你走到终点
res = Math.min(res, sum);
}
}
}
矩形相交的面积
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int x1 = in.nextInt();
int y1 = in.nextInt();
int w1 = in.nextInt();
int h1 = in.nextInt();
int x2 = in.nextInt();
int y2 = in.nextInt();
int w2 = in.nextInt();
int h2 = in.nextInt();
int x3 = in.nextInt();
int y3 = in.nextInt();
int w3 = in.nextInt();
int h3 = in.nextInt();
int w = getMin(x1 + w1, x2 + w2, x3 + w3) - getMax(x1, x2, x3);
int h = getMin(y1, y2, y3) - getMax(y1 - h1, y2 - h2, y3 - h3);
if (w <= 0 || h <= 0){
System.out.println(0);
return;
}
System.out.println(w * h);
}
public static int getMax(int a, int b, int c){
int max = Math.max(a, b);
return Math.max(max, c);
}
public static int getMin(int a, int b, int c){
int min = Math.min(a, b);
return Math.min(min, c);
}
}
最佳出牌方法【注意剪枝】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int res = Integer.MIN_VALUE;
static int score = 0;
static int total;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
String[] split = s.split("");
int[] arr = new int[14];
for (String s1 : split) {
if ("0".equals(s1)){
arr[10]++;
}else if ("J".equals(s1)){
arr[11]++;
}else if ("Q".equals(s1)){
arr[12]++;
}else if ("K".equals(s1)){
arr[13]++;
}else {
arr[Integer.parseInt(s1)]++;
}
}
for (int i : arr) {
if (i != 0){
total += i;
}
}
backtracking(arr, 0);
System.out.println(res);
}
public static void backtracking(int[] arr, int start) {
if (total == 0) {
res = Math.max(res, score);
return;
}
for (int i = start; i < arr.length; i++) {
if (arr[i] >= 1) { // 有搞头
score += i;
arr[i]--;
total--;
backtracking(arr, i);
total++;
score -= i;
arr[i]++;
if (i + 4 < arr.length && arr[i + 1] > 0 && arr[i + 2] > 0 && arr[i + 3] > 0 && arr[i + 4] > 0) {
score += (i + i + 1 + i + 2 + i + 3 + i + 4) * 2;
arr[i]--;
arr[i + 1]--;
arr[i + 2]--;
arr[i + 3]--;
arr[i + 4]--;
total -= 5;
backtracking(arr, i);
total += 5;
arr[i]++;
arr[i + 1]++;
arr[i + 2]++;
arr[i + 3]++;
arr[i + 4]++;
score -= (i + i + 1 + i + 2 + i + 3 + i + 4) * 2;
}
}
if (arr[i] >= 2) {
score += 2 * 2 * i;
arr[i] -= 2;
total -= 2;
backtracking(arr, i);
arr[i] += 2;
total += 2;
score -= 2 * 2 * i;
}
if (arr[i] >= 3) {
score += 2 * 3 * i;
arr[i] -= 3;
total -= 3;
backtracking(arr, i);
arr[i] += 3;
total += 3;
score -= 2 * 3 * i;
}
if (arr[i] == 4) {
score += 4 * i * 3;
arr[i] -= 4;
total -= 4;
backtracking(arr, i);
total += 4;
score -= 4 * i * 3;
arr[i] += 4;
}
}
}
}
259. 乘坐保密电梯【回溯】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static boolean[] isVisited;
static boolean flag = true;
static int res = 0;
static int target;
static List<Integer> list = new ArrayList<>();
static List<List<Integer>> lists = new ArrayList<>();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
target = in.nextInt();
int count = in.nextInt();
isVisited = new boolean[count];
Integer[] arr = new Integer[count];
for (int i = 0; i < arr.length; i++) {
arr[i] = in.nextInt();
}
Arrays.sort(arr, (o1, o2) -> o2 - o1);
backtracking(arr);
StringBuilder ans = new StringBuilder();
if (lists.size() == 0){
System.out.println(-1);
return;
}
List<Integer> list = lists.get(0);
for (Integer integer : list) {
ans.append(integer + " ");
}
System.out.println(ans.toString().trim());
}
public static void backtracking(Integer[] arr){
if (res <= target && list.size() == arr.length){
if (lists.size() == 0) {
lists.add(new ArrayList<>(list));
}else {
if (compare(lists.get(0), new ArrayList<>(list), target)){
lists.clear();
lists.add(new ArrayList<>(list));
}
}
return;
}
for (int i = 0; i < arr.length; i++) {
if (!isVisited[i]){
if (flag){ // flag 默认 flag
res += arr[i];
list.add(arr[i]);
flag = !flag;
}else {
res -= arr[i];
list.add(arr[i]);
flag = !flag;
}
isVisited[i] = true;
backtracking(arr);
list.remove(list.size() - 1);
isVisited[i] = false; // 反转
if (flag){
res += arr[i];
}else {
res -= arr[i];
}
flag = !flag;
}
}
}
public static boolean compare(List<Integer> list1, List<Integer> list2, int target){
int sum1 = 0;
int sum2 = 0;
for (int i = 0; i < list1.size(); i++) {
if (i % 2 == 0){
sum1 += list1.get(i);
sum2 += list2.get(i);
}else {
sum1 -= list1.get(i);
sum2 -= list2.get(i);
}
}
return (target - sum1) - (target - sum2) > 0;
}
}
没有回文串
思路:
下一个字符串
3
abc
其中第一行输入的数字3表示:限定了每位上的字母只能是英语字母前3个,即每位上字母只能取a,b,c。如果按照字典序来看,则相当于每位字母最大取c。
因此第二行输入的abc的下一个字典序字符串是:aca。
但是aca字符串含有了回文串aca,因此我们还要继续取下一个字典序字符串:acb,而acb是不含回文串的,因此abc的下一个字典序的、不包含回文串的、字符都是在英语字母的前N个、且长度相同的字符串是acb。
猜密码【按照字典序排序:A.compareTo(B)】
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static List<Integer> list = new ArrayList<>();
static List<List<Integer>> res = new ArrayList<>();
static int[] arr;
static int target;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] split = in.nextLine().split(",");
arr = new int[split.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.parseInt(split[i]);
}
target = in.nextInt();
backtracking(0);
if (res.size() == 0){
System.out.println("None");
return;
}
res.stream().forEach(list -> {
StringBuilder sb = new StringBuilder();
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
String A = o1 + "";
String B = o2 + "";
return A.compareTo(B);
}
});
for (Integer integer : list) {
sb.append(integer + ",");
}
System.out.println(sb.toString().substring(0, sb.length() - 1));
});
}
public static void backtracking(int start){
if (list.size() >= target){
res.add(new ArrayList<>(list));
}
for (int i = start; i < arr.length; i++) {
list.add(arr[i]);
backtracking(i + 1);
list.remove(list.size() - 1);
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix