modify code

master
algorithmzuo 3 years ago
parent 1872a726b1
commit 6dd4ed002d

@ -0,0 +1,185 @@
package class_2022_09_3_week;
// 来自360
// 有n个黑白棋子它们的一面是黑色一面是白色
// 它们被排成一行位置0~n-1上。一开始所有的棋子都是黑色向上
// 一共有q次操作每次操作将位置标号在区间[LR]内的所有棋子翻转
// 那么这个范围上的每一颗棋子的颜色也就都改变了
// 请在每次操作后求这n个棋子中黑色向上的棋子个数
// 1 <= n <= 10^18
// 1 <= q <= 300
// 0 <= 每一条操作的L、R <= n - 1
// 输出q行每一行一个整数表示操作后的所有黑色棋子的个数
// 注意 : 其实q <= 10^5也可以通过360考试时候降低了难度
public class Code01_BlackWhiteChess {
// 为了测试
// 暴力方法
public static class Right {
boolean[] white;
public Right(long n) {
white = new boolean[(int) n];
}
public void reverse(long l, long r) {
if (l <= r) {
for (int i = (int) l; i <= (int) r; i++) {
white[i] = !white[i];
}
}
}
public long blacks() {
long ans = 0;
for (boolean s : white) {
ans += !s ? 1 : 0;
}
return ans;
}
}
// 正式结构的实现
// 动态开点线段树
// 1 ~ 10^18 -> node
// l ~ r -> node
// l ~ r -> sum(黑子的数量)
// l ~ r -> 当前有没有翻转的动作需要往下传
public static class Node {
public long sum;
public boolean change;
public Node left;
public Node right;
public Node(long len) {
sum = len;
change = false;
}
}
// n = 10^18
// DynamicSegmentTree dst = new DynamicSegmentTree(n);
// int[] c1 = {4, 4000万} dst.reverse(c1[0], c1[1]) -> dst.blacks
// int[] c2 ...
// ...
// c1 [l, r] 翻转, 数量 1~n
// c2 [l, r] 翻转, 数量 1~n
public static class DynamicSegmentTree {
// 1 ~ n
public Node root;
public long size;
public DynamicSegmentTree(long n) {
root = new Node(n);
size = n;
}
public long blacks() {
return root.sum;
}
// l++ r++
// 0, 7 -> 1,8
// 4, 19 -> 5, 20
// 19, 4 -> 不操作
public void reverse(long l, long r) {
if (l <= r) {
l++;
r++;
reverse(root, 1, size, l, r);
}
}
// l...r 线段树范围 s...e 任务范围
// Node cur
private void reverse(Node cur, long l, long r, long s, long e) {
if (s <= l && r <= e) {
cur.change = !cur.change;
cur.sum = (r - l + 1) - cur.sum;
} else {
long m = (l + r) >> 1;
pushDown(cur, m - l + 1, r - m);
if (s <= m) {
reverse(cur.left, l, m, s, e);
}
if (e > m) {
reverse(cur.right, m + 1, r, s, e);
}
pushUp(cur);
}
}
private void pushDown(Node cur, long ln, long rn) {
if (cur.left == null) {
cur.left = new Node(ln);
}
if (cur.right == null) {
cur.right = new Node(rn);
}
if (cur.change) {
cur.left.change = !cur.left.change;
cur.left.sum = ln - cur.left.sum;
cur.right.change = !cur.right.change;
cur.right.sum = rn - cur.right.sum;
cur.change = false;
}
}
private void pushUp(Node cur) {
cur.sum = cur.left.sum + cur.right.sum;
}
}
public static void main(String[] args) {
int N = 1000;
int testTimes = 5000;
int opTimes = 500;
System.out.println("功能测试开始");
for (int i = 0; i < testTimes; i++) {
int n = (int) (Math.random() * N) + 1;
Right right = new Right(n);
DynamicSegmentTree dst = new DynamicSegmentTree(n);
boolean pass = true;
for (int j = 0; j < opTimes; j++) {
int a = (int) (Math.random() * n);
int b = (int) (Math.random() * n);
int l = Math.min(a, b);
int r = Math.max(a, b);
right.reverse(l, r);
dst.reverse(l, r);
if (right.blacks() != dst.blacks()) {
pass = false;
return;
}
}
if (!pass) {
System.out.println("出错了!");
break;
}
}
System.out.println("功能测试结束");
System.out.println("性能测试开始");
long n = 1000000000000000000L;
int ops = 100000;
System.out.println("数组范围 : " + n);
System.out.println("查询次数 : " + ops);
DynamicSegmentTree dst = new DynamicSegmentTree(n);
long start = System.currentTimeMillis();
for (int j = 0; j < ops; j++) {
long a = (long) (Math.random() * n);
long b = (long) (Math.random() * n);
long l = Math.min(a, b);
long r = Math.max(a, b);
dst.reverse(l, r);
}
long end = System.currentTimeMillis();
System.out.println("运行时间 : " + (end - start) + " 毫秒");
System.out.println("性能测试结束");
}
}

@ -0,0 +1,157 @@
package class_2022_09_3_week;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
// 来自美团
// 某天小美进入了一个迷宫探险,根据地图所示,这个迷宫里有无数个房间
// 序号分别为1、2、3、...入口房间的序号为1
// 任意序号为正整数x的房间都与序号 2*x 和 2*x + 1 的房间之间各有一条路径
// 但是这些路径是单向的即只能从序号为x的房间去到序号为 2*x 或 2*x+1 的房间
// 而不能从 2*x 或 2*x+1 的房间去到序号为x的房间
// 在任何时刻小美都可以选择结束探险并离开迷宫,但是离开之后将无法再次进入迷宫
// 小美还提前了解了迷宫中宝藏的信息
// 已知宝藏共有n个其中第i个宝藏在序号为pi的房间价值为wi
// 且一个房间中可能有多个宝藏
// 小美为了得到更多的宝藏,需要精心规划路线,她找到你帮忙
// 想请你帮她计算一下,能获得的宝藏价值和最大值为多少
// 第一行一个正整数n表示宝藏数量。
// 第二行为n个正整数p1, p2,...... pn其中pi表示第 i 个宝藏在序号为pi的房间。
// 第三行为n个正整数w1, w2,...... wn其中wi表示第i个宝藏的价值为wi。
// 1 <= n <= 40000, 1 <= pi < 2^30, 1 <= wi <= 10^6。
public class Code02_EntryRoomGetMoney {
// 为了测试
// 普通动态规划
public static int maxMoney1(int n, int[] p, int[] w) {
int[][] rooms = new int[n][2];
for (int i = 0; i < n; i++) {
rooms[i][0] = p[i];
rooms[i][1] = w[i];
}
Arrays.sort(rooms, (a, b) -> a[0] - b[0]);
int ans = 0;
int[] dp = new int[n];
Arrays.fill(dp, -1);
for (int i = 0; i < n; i++) {
ans = Math.max(ans, process1(i, rooms, n, dp));
}
return ans;
}
public static int process1(int index, int[][] rooms, int n, int[] dp) {
if (dp[index] != -1) {
return dp[index];
}
int next = 0;
for (int i = index + 1; i < n; i++) {
if (reach(rooms[index][0], rooms[i][0])) {
next = Math.max(next, process1(i, rooms, n, dp));
}
}
int ans = rooms[index][1] + next;
dp[index] = ans;
return dp[index];
}
public static boolean reach(int from, int to) {
while (to >= from) {
if (from == to) {
return true;
} else {
to /= 2;
}
}
return false;
}
// 正式方法
// 时间复杂度O(N)的动态规划
// 利用图来优化枚举
public static int maxMoney2(int n, int[] p, int[] w) {
int[][] rooms = new int[n][2];
for (int i = 0; i < n; i++) {
rooms[i][0] = p[i];
rooms[i][1] = w[i];
}
Arrays.sort(rooms, (a, b) -> a[0] - b[0]);
HashMap<Integer, Integer> first = new HashMap<>();
ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
for (int i = 0; i < n; i++) {
int to = rooms[i][0];
while (to > 0) {
if (first.containsKey(to)) {
graph.get(first.get(to)).add(i);
break;
} else {
to >>= 1;
}
}
graph.add(new ArrayList<>());
if (!first.containsKey(rooms[i][0])) {
first.put(rooms[i][0], i);
}
}
int ans = 0;
int[] dp = new int[n];
for (int i = n - 1; i >= 0; i--) {
int post = 0;
for (int next : graph.get(i)) {
if (rooms[next][0] == rooms[i][0]) {
dp[i] += dp[next];
} else {
post = Math.max(post, dp[next]);
}
}
dp[i] += post + rooms[i][1];
ans = Math.max(ans, dp[i]);
}
return ans;
}
// 为了测试
public static int[] randomArray(int n, int v) {
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
ans[i] = (int) (Math.random() * v) + 1;
}
return ans;
}
public static void main(String[] args) {
int N = 100;
int P = 5000;
int W = 5000;
int testTimes = 5000;
System.out.println("功能测试开始");
for (int i = 0; i < testTimes; i++) {
int n = (int) (Math.random() * N) + 1;
int[] p = randomArray(n, P);
int[] w = randomArray(n, W);
int ans1 = maxMoney1(n, p, w);
int ans2 = maxMoney2(n, p, w);
if (ans1 != ans2) {
System.out.println("出错了");
}
}
System.out.println("功能测试结束");
System.out.println("性能测试开始");
N = 50000;
P = 2000000000;
W = 1000000;
int[] p = randomArray(N, P);
int[] w = randomArray(N, W);
System.out.println("房间个数 : " + N);
System.out.println("位置范围 : " + P);
System.out.println("价值范围 : " + W);
long start = System.currentTimeMillis();
maxMoney2(N, p, w);
long end = System.currentTimeMillis();
System.out.println("运行时间 : " + (end - start) + " 毫秒");
System.out.println("性能测试结束");
}
}

@ -0,0 +1,98 @@
package class_2022_09_3_week;
// 来自美团
// 某天小美在玩一款游戏游戏开始时有n台机器
// 每台机器都有一个能量水平分别为a1、a2、…、an
// 小美每次操作可以选其中的一台机器假设选的是第i台
// 那小美可以将其变成 ai+10^kk为正整数且0<=k<=9
// 由于能量过高会有安全隐患,所以机器会在小美每次操作后会自动释放过高的能量
// 即变成 (ai+10^k)%m
// 其中%m表示对m取模由于小美还有工作没有完成所以她想请你帮她计算一下
// 对于每台机器将其调节至能量水平为0至少需要多少次操作
//(机器自动释放能量不计入小美的操作次数)。
// 第一行两个正整数n和m表示数字个数和取模数值。
// 第二行为n个正整数a1, a2,...... an其中ai表示第i台机器初始的能量水平。
// 1 <= n <= 300002 <= m <= 30000, 0 <= ai <= 10^12。
public class Code03_AllNumbersModToZeroMinTimes {
public static int[] times(int n, int m, int[] arr) {
// map[i] : i这个余数变成余数0需要至少操作几次
int[] map = new int[m];
bfs(m, map);
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
int num = arr[i];
int minTimes = Integer.MAX_VALUE;
if (num < m) {
minTimes = map[num];
} else {
for (int j = 0; j <= 9; j++) {
int mod = (int) (((long) num + (long) Math.pow(10, j)) % m);
minTimes = Math.min(minTimes, map[mod] + 1);
}
}
ans[i] = minTimes;
}
return ans;
}
public static void bfs(int m, int[] map) {
boolean[] visited = new boolean[m];
visited[0] = true;
int[] queue = new int[m];
int l = 0;
int r = 1;
// map[0] == 0
// 表示余数0变成余数0需要至少0次
// 0进队列了, queue[0] = 0
// 0算访问过了visited[0] = true
while (l < r) {
// 当前弹出的余数是cur
int cur = queue[l++];
// 能加的数字从1枚举到10^9
for (int add = 1; add <= 1000000000; add *= 10) {
// 比如m == 7
// 当前余数是curcur变成余数0至少要a次
// 我们想知道 : (哪个余数b + add) % m == cur
// 比如,add=10的时候cur==5的时候
// 我们想知道 : (哪个余数b + 10) % 7 == 5
// 因为10 % 7 = 3
// 所以其实我们在求 : 哪个余数b + 3 == 5
// 显然b = 5 - 3 = cur - (add % m) = 2
// 再比如add=10的时候cur==2的时候
// 我们想知道 : (哪个余数b + 10) % 7 == 2
// 因为10 % 7 = 3
// 所以其实我们在求 : 哪个余数b + 3 == 2
// 这明显是不对的,
// 所以其实我们在求 : 哪个余数b + 3 == 2 + m == 9
// 也就是b通过加了add % m来到了m + cur多转了一圈
// b = 9 - 3 = cur - (add % m) + m = 6
// 也就是说b = cur - (add % m)
// 如果不小于0那就是这个b是我们要找的余数
// 如果小于0那就是b+m是我们要找的余数
int from = cur - (add % m);
if (from < 0) {
from += m;
}
// 这个余数我们终于找到了因为cur变成余数0需要a次
// 所以这个余数变成余数0需要a+1次
// 当然前提是这个余数,之前宽度优先遍历的时候,没遇到过
if (!visited[from]) {
visited[from] = true;
map[from] = map[cur] + 1;
queue[r++] = from;
}
}
}
}
public static void main(String[] args) {
int m = 100;
int[] map = new int[m];
bfs(m, map);
for (int i = 0; i < m; i++) {
System.out.println(i + " , " + map[i]);
}
}
}

@ -0,0 +1,120 @@
package class_2022_09_3_week;
import java.util.Arrays;
// 来自美团
// 有三个题库A、B、C每个题库均有n道题目且题目都是从1到n进行编号
// 每个题目都有一个难度值
// 题库A中第i个题目的难度为ai
// 题库B中第i个题目的难度为bi
// 题库C中第i个题目的难度为ci
// 小美准备组合出一套试题,试题共有三道题,
// 第一题来自题库A第二题来自题库B第三题来自题库C
// 试题要求题目难度递增,且梯度不能过大
// 具体地说,第二题的难度必须大于第一题的难度,但不能大于第一题难度的两倍
// 第三题的难度必须大于第二题的难度,但不能大于第二题难度的两倍
// 小美想知道在满足上述要求下,有多少种不同的题目组合
//(三道题目中只要存在一道题目不同,则两个题目组合就视为不同
// 输入描述 第一行一个正整数n, 表示每个题库的题目数量
// 第二行为n个正整数a1, a2,...... an其中ai表示题库A中第i个题目的难度值
// 第三行为n个正整数b1, b2,...... bn其中bi表示题库B中第i个题目的难度值
// 第四行为n个正整数c1, c2,...... cn其中ci表示题库C中第i个题目的难度值
// 1 <= n <= 20000, 1 <= ai, bi, ci <= 10^9。
public class Code04_ExaminationPaperWays {
// 暴力方法
// 时间复杂度O(N^3)
// 为了验证
public static int ways1(int[] a, int[] b, int[] c) {
int n = a.length;
Arrays.sort(a);
Arrays.sort(b);
Arrays.sort(c);
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n && b[j] <= a[i] * 2; j++) {
if (b[j] > a[i]) {
for (int k = 0; k < n && c[k] <= b[j] * 2; k++) {
if (c[k] > b[j]) {
ans++;
}
}
}
}
}
return ans;
}
// 正式方法
// 时间复杂度O(N * logN)
public static int ways2(int[] a, int[] b, int[] c) {
int n = a.length;
Arrays.sort(a);
Arrays.sort(b);
Arrays.sort(c);
// B里面的记录
int[] help = new int[n];
for (int i = 0, l = -1, r = 0; i < n; i++) {
while (l + 1 < n && c[l + 1] <= b[i]) {
l++;
}
while (r < n && c[r] <= b[i] * 2) {
r++;
}
help[i] = Math.max(r - l - 1, 0);
}
for (int i = 1; i < n; i++) {
help[i] += help[i - 1];
}
int ans = 0;
for (int i = 0, l = -1, r = 0; i < n; i++) {
while (l + 1 < n && b[l + 1] <= a[i]) {
l++;
}
while (r < n && b[r] <= a[i] * 2) {
r++;
}
if (r - l - 1 > 0) {
ans += sum(help, l + 1, r - 1);
}
}
return ans;
}
public static int sum(int[] help, int l, int r) {
return l == 0 ? help[r] : help[r] - help[l - 1];
}
// 为了测试
public static int[] randomArray(int n, int v) {
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
ans[i] = (int) (Math.random() * v);
}
return ans;
}
// 为了测试
public static void main(String[] args) {
int N = 100;
int V = 100;
int testTimes = 5000;
System.out.println("测试开始");
for (int i = 0; i < testTimes; i++) {
int n = (int) (Math.random() * N) + 1;
int[] a = randomArray(n, V);
int[] b = randomArray(n, V);
int[] c = randomArray(n, V);
int ans1 = ways1(a, b, c);
int ans2 = ways2(a, b, c);
if (ans1 != ans2) {
System.out.println("出错了!");
System.out.println(ans1);
System.out.println(ans2);
break;
}
}
System.out.println("测试结束");
}
}

@ -0,0 +1,130 @@
package class_2022_09_3_week;
// 来自字节
// 给定一个只由小写字母组成的字符串str长度为N
// 给定一个只由0、1组成的数组arr长度为N
// arr[i] == 0表示str中i位置的字符不许修改
// arr[i] == 1表示str中i位置的字符允许修改
// 给定一个正数m表示在任意允许修改的位置
// 可以把该位置的字符变成a~z中的任何一个
// 可以修改m次
// 返回在最多修改m次的情况下全是一种字符的最长子串是多长
// 1 <= N, M <= 10^5
// 所有字符都是小写
public class Code05_MaxLengthSameCharMChanges {
// 暴力方法
// 为了测试
public static int maxLen1(String str, int[] arr, int m) {
char[] s = str.toCharArray();
int n = s.length;
int ans = 0;
for (char c = 'a'; c <= 'z'; c++) {
for (int i = 0; i < n; i++) {
for (int j = n - 1; j >= i; j--) {
if (ok(s, i, j, c, arr, m)) {
ans = Math.max(ans, j - i + 1);
break;
}
}
}
}
return ans;
}
// 为了测试
public static boolean ok(char[] s, int l, int r, char c, int[] arr, int m) {
for (int i = l; i <= r; i++) {
if (s[i] == c) {
continue;
}
if (arr[i] == 0 || m == 0) {
return false;
}
m--;
}
return true;
}
// 正式方法
public static int maxLen2(String str, int[] arr, int m) {
char[] s = str.toCharArray();
int n = s.length;
int ans = 0;
for (char aim = 'a'; aim <= 'z'; aim++) {
// 右边界
// [l..r)
int r = 0;
// 用了几次修改了
// change == m 用完的时候
int change = 0;
for (int l = 0; l < n; l++) {
// l......r ->
while (r < n) {
if (s[r] == aim) {
r++;
continue;
}
// s[r] != aim
if (arr[r] == 0 || change == m) {
break;
}
// s[r] != aim && arr[r] == 1 && change < m
change++;
r++;
}
// l....r-1 r
// X l+1
ans = Math.max(ans, r - l);
if (s[l] != aim && arr[l] == 1) {
change--;
}
// r r
// l l
// X
r = Math.max(r, l + 1);
}
}
return ans;
}
// 为了测试
public static String randomString(int n, int r) {
char[] ans = new char[n];
for (int i = 0; i < n; i++) {
ans[i] = (char) ((int) (Math.random() * r) + 'a');
}
return String.valueOf(ans);
}
// 为了测试
public static int[] randomArray(int n) {
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
ans[i] = (int) (Math.random() * 2);
}
return ans;
}
// 为了测试
public static void main(String[] args) {
int N = 100;
int R = 5;
int testTimes = 5000;
System.out.println("测试开始");
for (int i = 0; i < testTimes; i++) {
int n = (int) (Math.random() * N) + 1;
int m = (int) (Math.random() * n) + 1;
String str = randomString(n, R);
int[] arr = randomArray(n);
int ans1 = maxLen1(str, arr, m);
int ans2 = maxLen2(str, arr, m);
if (ans1 != ans2) {
System.out.println("出错了!");
break;
}
}
System.out.println("测试结束");
}
}

@ -0,0 +1,103 @@
package class_2022_09_3_week;
// 来自阿里
// 小红定义一个仅有r、e、d三种字符的字符串中
// 如果仅有一个长度不小于2的回文子串那么这个字符串定义为"好串"
// 给定一个正整数n输出长度为n的好串有多少个
// 结果对10^9 + 7取模 1 <= n <= 10^9
// 示例:
// n = 1, 输出0
// n = 2, 输出3
// n = 3, 输出18
// https://www.mashibing.com/question/detail/37485
public class Code06_RedPalindromeGoodStrings {
// 暴力方法
// 为了观察规律
// 具体方法论在体系学习班章节39 : 根据对数器找规律
public static int num1(int n) {
char[] path = new char[n];
return process1(path, 0);
}
public static int process1(char[] path, int i) {
if (i == path.length) {
int[] dp = getManacherDP(path);
int cnt = 0;
for (int p : dp) {
if (p - 1 > 3) {
return 0;
}
if (p - 1 >= 2) {
cnt++;
}
if (cnt > 1) {
return 0;
}
}
return cnt == 1 ? 1 : 0;
} else {
int ans = 0;
path[i] = 'r';
ans += process1(path, i + 1);
path[i] = 'e';
ans += process1(path, i + 1);
path[i] = 'd';
ans += process1(path, i + 1);
return ans;
}
}
public static int[] getManacherDP(char[] s) {
char[] str = manacherString(s);
int[] pArr = new int[str.length];
int C = -1;
int R = -1;
for (int i = 0; i < str.length; i++) {
pArr[i] = R > i ? Math.min(pArr[2 * C - i], R - i) : 1;
while (i + pArr[i] < str.length && i - pArr[i] > -1) {
if (str[i + pArr[i]] == str[i - pArr[i]])
pArr[i]++;
else {
break;
}
}
if (i + pArr[i] > R) {
R = i + pArr[i];
C = i;
}
}
return pArr;
}
public static char[] manacherString(char[] s) {
char[] res = new char[s.length * 2 + 1];
int index = 0;
for (int i = 0; i != res.length; i++) {
res[i] = (i & 1) == 0 ? '#' : s[index++];
}
return res;
}
// 正式方法
// 观察规律之后,把规律变成代码
public static int num2(int n) {
if (n == 1) {
return 0;
}
if (n == 2) {
return 3;
}
if (n == 3) {
return 18;
}
return 6 * (n + 1);
}
public static void main(String[] args) {
for (int i = 1; i <= 10; i++) {
System.out.println("长度为" + i + ", 答案:" + num1(i) + "," + num2(i));
}
}
}

@ -1895,3 +1895,98 @@ op[i] = { k , 1 }, 表示对前k个士兵执行从大到小的操作
0 <= 修改机会 <= 10^6
第041节 2022年9月第3周流行算法题目解析
来自360
有n个黑白棋子它们的一面是黑色一面是白色
它们被排成一行位置0~n-1上。一开始所有的棋子都是黑色向上
一共有q次操作每次操作将位置标号在区间[LR]内的所有棋子翻转
那么这个范围上的每一颗棋子的颜色也就都改变了
请在每次操作后求这n个棋子中黑色向上的棋子个数
1 <= n <= 10^18
1 <= q <= 300
0 <= 每一条操作的L、R <= n - 1
输出q行每一行一个整数表示操作后的所有黑色棋子的个数
注意 : 其实q <= 10^5也可以通过360考试时候降低了难度
来自美团
某天小美进入了一个迷宫探险,根据地图所示,这个迷宫里有无数个房间
序号分别为1、2、3、...入口房间的序号为1
任意序号为正整数x的房间都与序号 2*x 和 2*x + 1 的房间之间各有一条路径
但是这些路径是单向的即只能从序号为x的房间去到序号为 2*x 或 2*x+1 的房间
而不能从 2*x 或 2*x+1 的房间去到序号为x的房间
在任何时刻小美都可以选择结束探险并离开迷宫,但是离开之后将无法再次进入迷宫
小美还提前了解了迷宫中宝藏的信息
已知宝藏共有n个其中第i个宝藏在序号为pi的房间价值为wi
且一个房间中可能有多个宝藏
小美为了得到更多的宝藏,需要精心规划路线,她找到你帮忙
想请你帮她计算一下,能获得的宝藏价值和最大值为多少
第一行一个正整数n表示宝藏数量。
第二行为n个正整数p1, p2,...... pn其中pi表示第 i 个宝藏在序号为pi的房间。
第三行为n个正整数w1, w2,...... wn其中wi表示第i个宝藏的价值为wi。
1 <= n <= 40000, 1 <= pi < 2^30, 1 <= wi <= 10^6。
来自美团
某天小美在玩一款游戏游戏开始时有n台机器
每台机器都有一个能量水平分别为a1、a2、…、an
小美每次操作可以选其中的一台机器假设选的是第i台
那小美可以将其变成 ai+10^kk为正整数且0<=k<=9
由于能量过高会有安全隐患,所以机器会在小美每次操作后会自动释放过高的能量
即变成 (ai+10^k)%m
其中%m表示对m取模由于小美还有工作没有完成所以她想请你帮她计算一下
对于每台机器将其调节至能量水平为0至少需要多少次操作
机器自动释放能量不计入小美的操作次数)。
第一行两个正整数n和m表示数字个数和取模数值。
第二行为n个正整数a1, a2,...... an其中ai表示第i台机器初始的能量水平。
1 <= n <= 300002 <= m <= 30000, 0 <= ai <= 10^12。
来自美团
有三个题库A、B、C每个题库均有n道题目且题目都是从1到n进行编号
每个题目都有一个难度值
题库A中第i个题目的难度为ai
题库B中第i个题目的难度为bi
题库C中第i个题目的难度为ci
小美准备组合出一套试题,试题共有三道题,
第一题来自题库A第二题来自题库B第三题来自题库C
试题要求题目难度递增,且梯度不能过大
具体地说,第二题的难度必须大于第一题的难度,但不能大于第一题难度的两倍
第三题的难度必须大于第二题的难度,但不能大于第二题难度的两倍
小美想知道在满足上述要求下,有多少种不同的题目组合
(三道题目中只要存在一道题目不同,则两个题目组合就视为不同
输入描述 第一行一个正整数n, 表示每个题库的题目数量
第二行为n个正整数a1, a2,...... an其中ai表示题库A中第i个题目的难度值
第三行为n个正整数b1, b2,...... bn其中bi表示题库B中第i个题目的难度值
第四行为n个正整数c1, c2,...... cn其中ci表示题库C中第i个题目的难度值
1 <= n <= 20000, 1 <= ai, bi, ci <= 10^9。
来自字节
给定一个只由小写字母组成的字符串str长度为N
给定一个只由0、1组成的数组arr长度为N
arr[i] == 0表示str中i位置的字符不许修改
arr[i] == 1表示str中i位置的字符允许修改
给定一个正数m表示在任意允许修改的位置
可以把该位置的字符变成a~z中的任何一个
可以修改m次
返回在最多修改m次的情况下全是一种字符的最长子串是多长
1 <= N, M <= 10^5
所有字符都是小写
来自阿里
小红定义一个仅有r、e、d三种字符的字符串中
如果仅有一个长度不小于2的回文子串那么这个字符串定义为"好串"
给定一个正整数n输出长度为n的好串有多少个
结果对10^9 + 7取模 1 <= n <= 10^9
示例:
n = 1, 输出0
n = 2, 输出3
n = 3, 输出18
https://www.mashibing.com/question/detail/37485

Loading…
Cancel
Save