第一题
给你一个数组,你可以选择其中的一个区间,并将区间中的每个字符翻转,(定义翻转一个数字指数字正着读变成倒着读,例如”1234"变成”4321”"1430"变成”341”,不包含前导零)求操作后区间和最大可能值。
输入描述
第一行输入一个正整数n,代表数组的大小。
第二行输入n个正整数ai ,代表数组的元素
1<=n<=10e5
1<=ai<=1e9
输出描述
一个整数代表结束之后的最大值
解析
求出每一个翻转后的数与原数的差值,就把题目转成了求最大区间和问题。力扣原题
JAVA代码
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
long[] nums = new long[n];
long sum = 0;
for (int i = 0; i < n; i++) {
nums[i] = in.nextLong();
sum += nums[i];
StringBuilder s = new StringBuilder();
s.append(nums[i]);
nums[i] = Long.valueOf(s.reverse().toString()) - nums[i];
}
long pre = 0, maxAns = nums[0];
for (long x : nums) {
pre = Math.max(pre + x, x);
maxAns = Math.max(maxAns, pre);
}
sum += maxAns;
System.out.println(sum);
}
}
第二题
给你一个字符矩阵,只允许你走"日"字,类似象棋中的马,如果当前的坐标是(x0, y0),那么落点的坐标(x,y)必须满足|x-x0| +|y-y0|= 3且 x≠x0, y≠y0)你可以任选起点,问有多少种走的方案使得路径字符串为"byte"
解析
从每个字符‘b’开始DFS
JAVA代码
import java.util.*;
public class Main {
static char[] target = { 'b', 'y', 't', 'e' };
static int[][] d = { { 1, 2 }, { 2, 1 }, { -1, 2 }, { 2, -1 }, { -1, -2 }, { -2, -1 }, { -2, 1 }, { 1, -2 } };
static int ans = 0;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
char[][] arr = new char[n][m];
for (int i = 0; i < n; i++)
arr[i] = in.next().toCharArray();
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (arr[i][j] == target[0]) {
dfs(i, j, arr, 1);
}
}
}
System.out.print(ans);
}
public static void dfs(int x, int y, char[][] c, int res) {
if (res == target.length) {
ans++;
return;
}
for (int i = 0; i < d.length; i++) {
int x1 = x + d[i][0];
int y1 = y + d[i][1];
if (x1 < 0 || x1 >= c.length || y1 < 0 || y1 >= c[0].length || c[x1][y1] != target[res])
continue;
dfs(x1, y1, c, res + 1);
}
}
}
第三题
小红在一个长度为n的数组上,初始在第一个元素,她准备前往最后一个元素。小红有一个弹力鞋,她每次可以利用弹力鞋向右弹跳,初始弹力鞋只能跳 1的距离,每跳一次弹力鞋能跳的距离翻倍。例如,第一次跳的距离恰好是1,第二次跳的距离恰好是2,第三次跳的距离恰好是4,以此类推。另外小红可以随时将弹力鞋弹跳的距离重置为 1。现在数组上有若干个单向传送阵,小红可以随时使用这些传送阵向右传送 (传送后弹力鞋的距离强制重置为 1)。小红想知道,自己需要至少弹跳多少次可以到达最后一个元素?
解析
简单DP,我们考虑每个节点的两种转移情况:1.从之前的节点跳2的幂次,消耗幂次的次数 2.通过传送门过来,不消耗次数
dp[i][j]表示从起点到i点使用了j次弹力鞋的最小次数
对于情况1我们对于每个节点向后更新从当前点开始每个幂次的节点的答案
对于情况2直接更新对应传送终点的最小值即可
JAVA代码
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
int[][] dp = new int[n][23];
for (int i = 0; i < n; i++)
Arrays.fill(dp[i], (int) 1e9);
int[] f = new int[n];// 表示使用传送阵的最小到达;
Arrays.fill(f, (int) 1e9);
if (arr[0] != -1)
f[arr[0] - 1] = 0;
for (int i = 1; i < n; i++) {
if (f[i] != (int) 1e9) {
dp[i][0] = f[i];
}
int ans = 1;
int min = dp[i][0];
for (int j = 1; j < 23; j++) {
if (i >= ans) {
dp[i][j] = Math.min(dp[i - ans][j - 1] + 1, dp[i][j]);
}
ans *= 2;
min = Math.min(min, dp[i][j]);
}
if (arr[i] != -1)
f[arr[i] - 1] = Math.min(f[arr[i] - 1], min);
dp[i][0] = min;
}
int min = (int) 1e9;
for (int i = 0; i < 23; i++) {
min = Math.min(min, dp[n - 1][i]);
}
System.out.println(min);
}
}