modify code

master
algorithmzuo 2 years ago
parent 7f88ec6074
commit 1a4b3862a2

@ -0,0 +1,67 @@
package class_2023_04_3_week;
// 来自华为OD
// 完美走位问题
// 给定一个由'W'、'A'、'S'、'D'四种字符组成的字符串长度一定是4的倍数
// 你可以把任意连续的一段子串,变成'W'、'A'、'S'、'D'组成的随意状态
// 目的是让4种字符词频一样
// 返回需要修改的最短子串长度
// 找到了出处是leetcode原题
// 测试链接 : https://leetcode.cn/problems/replace-the-substring-for-balanced-string/
public class Code01_ReplaceTheSubstringForBalancedString {
// Q W E R
// 0 1 2 3
public static int balancedString(String str) {
int n = str.length();
int[] arr = new int[n];
int[] cnts = new int[4];
for (int i = 0; i < n; i++) {
char c = str.charAt(i);
arr[i] = c == 'W' ? 1 : (c == 'E' ? 2 : (c == 'R' ? 3 : 0));
cnts[arr[i]]++;
}
int ans = n;
// L = 0......
// 1.....
// 2....r
// 3......
for (int l = 0, r = 0; l < n; l++) {
// !ok(cnts, l, r) , 当前窗口[l....r),如果不能让四种字符一样多!
// && r < n虽然没达标但是还有努力空间
while (!ok(cnts, l, r) && r < n) {
cnts[arr[r++]]--;
}
// 1) ok了
// 2) 依然不ok而且也没努力空间了
if (ok(cnts, l, r)) {
ans = Math.min(ans, r - l);
} else {
break;
}
cnts[arr[l]]++;
}
return ans;
}
// 窗口str[l.....r),你可以自由变化,但是窗口外的不能变化
// l = 3, r = 10
// [3....9]
// 窗口长度 = r - l
// cnts窗口之外每一种字符的词频统计不能算窗口内的统计的
// w : cnts[0]
// a : cnts[1]
// s : cnts[2]
// d : cnts[3]
// cnts只有4长度
public static boolean ok(int[] cnts, int l, int r) {
// 窗口外最大词频是多少
int maxCnt = Math.max(Math.max(cnts[0], cnts[1]), Math.max(cnts[2], cnts[3]));
// 需要多少空间拉平changes
// maxCnt - cnts[0] + maxCnt - cnts[1] maxCnt - cnts[2] maxCnt - cnts[3]
int changes = maxCnt * 4 - cnts[0] - cnts[1] - cnts[2] - cnts[3];
int rest = r - l - changes;
return rest >= 0 && rest % 4 == 0;
}
}

@ -0,0 +1,65 @@
package class_2023_04_3_week;
// 来自腾讯笔试
// 给定一个长度为N的正数数组还有一个正数K
// 返回有多少子序列的最大公约数为K
// 结果可能很大对1000000007取模
// 原题目简单转化就是如下的题目
// 测试链接 : https://www.luogu.com.cn/problem/CF803F
// 所以课上会讲怎么转化,然后就是讲测试链接里的题目
// 1 <= N <= 10^5
// 1 <= arr[i] <= 10^5
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的所有代码,并把主类名改成"Main"
// 可以直接通过
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
public class Code02_NumberOfSubsetGcdEqualK {
public static int MAXN = 100001;
public static int mod = 1000000007;
public static long[] dp = new long[MAXN];
public static long[] cnt = new long[MAXN];
public static long[] pow2 = new long[MAXN];
public static int n, v;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer in = new StreamTokenizer(br);
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
while (in.nextToken() != StreamTokenizer.TT_EOF) {
n = (int) in.nval;
pow2[0] = 1;
for (int i = 1; i <= n; i++) {
in.nextToken();
v = (int) in.nval;
cnt[v]++;
pow2[i] = (pow2[i - 1] * 2) % mod;
}
for (int i = MAXN - 1; i >= 1; i--) {
long counts = 0;
for (int j = i; j < MAXN; j += i) {
counts = (counts + cnt[j]) % mod;
}
dp[i] = (pow2[(int) counts] - 1 + mod) % mod;
for (int j = 2 * i; j < MAXN; j += i) {
dp[i] = (dp[i] - dp[j] + mod) % mod;
}
}
out.println(dp[1]);
out.flush();
}
}
}

@ -0,0 +1,117 @@
package class_2023_04_3_week;
// 来自学员问题,蓝桥杯练习题
// 给定一个长度为n的数组arr
// 现在你有一次机会, 将其中连续的K个数全修改成任意一个值
// 请你计算如何修改可以使修改后的数 列的最长不下降子序列最长
// 请输出这个最长的长度。
// 最长不下降子序列:子序列中的每个数不小于在它之前的数
// 1 <= k, n <= 10^5
// 1 <= arr[i] <= 10^6
// 测试链接 : https://www.luogu.com.cn/problem/P8776
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的所有代码,并把主类名改成"Main"
// 可以直接通过
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
public class Code03_LongestNoDecreaseModifyKSubarray {
public static int MAXN = 100001;
public static int[] arr = new int[MAXN];
public static int[] right = new int[MAXN];
public static int[] ends = new int[MAXN];
public static int n, k;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer in = new StreamTokenizer(br);
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
while (in.nextToken() != StreamTokenizer.TT_EOF) {
n = (int) in.nval;
in.nextToken();
k = (int) (in.nval);
for (int i = 1; i <= n; i++) {
in.nextToken();
arr[i] = (int) in.nval;
}
if (k >= n) {
out.println(n);
} else {
right();
out.println(getAns());
}
out.flush();
}
}
public static void right() {
right[n] = 1;
ends[1] = arr[n];
int len = 1;
for (int i = n - 1; i > 0; i--) {
int l = 1;
int r = len;
int m, find = len + 1;
while (l <= r) {
m = (l + r) / 2;
if (ends[m] < arr[i]) {
find = m;
r = m - 1;
} else {
l = m + 1;
}
}
ends[find] = arr[i];
len = Math.max(len, find);
right[i] = find;
}
}
public static int getAns() {
int ans = 0;
int len = 0;
for (int i = k + 1, j = 1; i <= n; i++, j++) {
int l = 1;
int r = len;
int m, find = len + 1;
while (l <= r) {
m = (l + r) / 2;
// 当前的arr[i], 利用之前的ends求左边长度
if (ends[m] > arr[i]) {
find = m;
r = m - 1;
} else {
l = m + 1;
}
}
ans = Math.max(ans, find + right[i] - 1 + k);
l = 1;
r = len;
find = len + 1;
while (l <= r) {
m = (l + r) / 2;
if (ends[m] > arr[j]) {
find = m;
r = m - 1;
} else {
l = m + 1;
}
}
len = Math.max(len, find);
ends[find] = arr[j];
}
ans = Math.max(ans, len + k);
return ans;
}
}

@ -3439,11 +3439,37 @@ subtexti == subtextk - i + 1 表示所有 i 的有效值( 即 1 <= i <= k )
第066节 2023年4月第3周流行算法题目解析
来自华为OD
完美走位问题
给定一个由'W'、'A'、'S'、'D'四种字符组成的字符串长度一定是4的倍数
你可以把任意连续的一段子串,变成'W'、'A'、'S'、'D'组成的随意状态
目的是让4种字符词频一样
返回需要修改的最短子串长度
找到了出处是leetcode原题
测试链接 : https://leetcode.cn/problems/replace-the-substring-for-balanced-string/
来自腾讯笔试
给定一个长度为N的正数数组还有一个正数K
返回有多少子序列的最大公约数为K
结果可能很大对1000000007取模
原题目简单转化就是如下的题目
测试链接 : https://www.luogu.com.cn/problem/CF803F
所以课上会讲怎么转化,然后就是讲测试链接里的题目
1 <= N <= 10^5
1 <= arr[i] <= 10^5
(上课时网络卡顿,将在下节课安排重讲)
来自学员问题,蓝桥杯练习题
给定一个长度为n的数组arr
现在你有一次机会, 将其中连续的K个数全修改成任意一个值
请你计算如何修改可以使修改后的数 列的最长不下降子序列最长
请输出这个最长的长度。
最长不下降子序列:子序列中的每个数不小于在它之前的数
1 <= k, n <= 10^5
1 <= arr[i] <= 10^6
测试链接 : https://www.luogu.com.cn/problem/P8776

Loading…
Cancel
Save