CD26 子数组的最大累加和问题
public class CD26_1
{
public static int solution(int[] arr)
{
int ans = -1, sum = 0;
for (int num : arr)
{
if (sum + num > 0)
{
sum += num;
ans = Math.max(ans, sum);
}
else
sum = 0;
}
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n;
n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr));
}
}
CD27 子矩阵的最大累加和问题
public class CD27_1
{
public static int solution(int[][] arr)
{
int[] temp;
int sum = 0, ans = -1;
for (int i = 0; i < arr.length; i++)
{
temp = new int[arr[0].length];
for (int j = i; j < arr.length; j++)
{
sum = 0;
for (int k = 0; k < arr[0].length; k++)
{
temp[k] += arr[j][k];
if (sum + temp[k] > 0)
{
sum += temp[k];
ans = Math.max(ans, sum);
}
else sum = 0;
}
}
}
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, m;
n = in.nextInt();
m = in.nextInt();
int[][] arr = new int[n][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
arr[i][j] = in.nextInt();
System.out.println(solution(arr));
}
}
CD28 在数组中找到一个局部最小的位置⭐
/* ⭐二分查找并不是数组有序时才能使用⭐ */
public class CD28_1
{
public static int solution(int[] arr)
{
if (arr == null || arr.length == 0) return -1;
if (arr.length == 1 || arr[0] < arr[1]) return 0;
if (arr[arr.length - 1] < arr[arr.length - 2]) return arr.length - 1;
int l = 1, r = arr.length - 2, mid;
while (l <= r)
{
mid = (l + r) / 2;
if (arr[mid] > arr[mid - 1]) r = mid - 1;
else if (arr[mid] > arr[mid + 1]) l = mid + 1;
else return mid;
}
return -1;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n;
n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr));
}
}
CD32 数组中子数组的最大累乘积⭐
/*⭐*/
public class CD32_1
{
public static String solution(double[] arr)
{
double mmax = arr[0], mmin = arr[0], ans = arr[0];
for (int i = 1; i < arr.length; i++)
{
double temp1 = mmax * arr[i], temp2 = mmin * arr[i];
mmax = Math.max(Math.max(temp1, temp2), arr[i]);
mmin = Math.min(Math.min(temp1, temp2), arr[i]);
ans = Math.max(ans, mmax);
}
return String.format("%.2f", ans);
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n;
n = in.nextInt();
double[] arr = new double[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextDouble();
System.out.println(solution(arr));
}
}
CD34 打印 N 个数组整体最大的 Top K
/* 模拟堆 */
public class CD34_1
{
public static class Node
{
public int val;
public int idx;
public int th;
public Node()
{
}
public Node(int val, int idx, int th)
{
this.val = val;
this.idx = idx;
this.th = th;
}
}
public static int[] solution(ArrayList<Integer>[] arr, int k)
{
int[] ans = new int[k];
Node[] h = new Node[arr.length];
int size = -1, index = 0;
for (int i = 0; i < arr.length; i++)
if (arr[i].size() != 0)
h[++size] = new Node(arr[i].get(arr[i].size() - 1), arr[i].size() - 1, i);
createHeap(h, size);
while (index < k)
{
Node maxNode = h[0];
ans[index++] = maxNode.val;
if (maxNode.idx != 0)
{
h[0] = new Node(arr[maxNode.th].get(maxNode.idx - 1), maxNode.idx - 1, maxNode.th);
adjustHeap(h, 0, size);
}
else
{
h[0] = h[size];
adjustHeap(h, 0, --size);
}
}
return ans;
}
public static void createHeap(Node[] arr, int len)
{
for (int i = (len - 1) / 2; i >= 0; i--)
adjustHeap(arr, i, len);
}
public static void adjustHeap(Node[] arr, int idx, int len)
{
int cur;
while (2 * idx + 1 <= len)
{
cur = 2 * idx + 1;
if (2 * idx + 2 <= len && arr[2 * idx + 1].val < arr[2 * idx + 2].val)
cur++;
if (arr[idx].val < arr[cur].val)
{
Node temp = arr[idx];
arr[idx] = arr[cur];
arr[cur] = temp;
}
else break;
idx = cur;
}
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int N, k, n;
N = in.nextInt();
k = in.nextInt();
ArrayList<Integer>[] arr = new ArrayList[N];
Arrays.setAll(arr, e -> new ArrayList<Integer>());
for (int i = 0; i < N; i++)
{
n = in.nextInt();
while (n-- > 0)
arr[i].add(in.nextInt());
}
int[] res = solution(arr, k);
System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
}
CD41 边界都是 1 的最大正方形大小
/* 模拟 */
public class CD41_1
{
public static int solution(int[][] arr)
{
int len = arr.length, ans = -1;
int[][] row = new int[len][len];
int[][] col = new int[len][len];
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++)
if (j == 0) row[i][j] = arr[i][j];
else row[i][j] = row[i][j - 1] + arr[i][j];
for (int j = 0; j < len; j++)
for (int i = 0; i < len; i++)
if (i == 0) col[i][j] = arr[i][j];
else col[i][j] = col[i - 1][j] + arr[i][j];
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++)
for (int l = Math.min(len - i, len - j); l >= 2; l--)
if (row[i][j + l - 1] - row[i][j] == l - 1 && col[i + l - 1][j] - col[i][j] == l - 1
&& row[i + l - 1][j + l - 1] - row[i + l - 1][j] == l - 1 && col[i + l - 1][j + l - 1] - col[i][j + l - 1] == l - 1)
ans = Math.max(ans, l);
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n;
n = in.nextInt();
int[][] arr = new int[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
arr[i][j] = in.nextInt();
System.out.println(solution(arr));
}
}
CD35 不包含本位置值的累乘数组
public class CD35_1
{
public static long[] solution(int[] arr, int p)
{
long[] suffix = new long[arr.length + 1];
long[] ans = new long[arr.length];
long prefix = 1;
suffix[arr.length] = 1;
for (int i = arr.length - 1; i >= 0; i--)
suffix[i] = (suffix[i + 1] * (arr[i] % p)) % p;
for (int i = 0; i < arr.length; i++)
{
ans[i] = (prefix * suffix[i + 1]) % p;
prefix = (prefix * (arr[i] % p)) % p;
}
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, p;
n = in.nextInt();
p = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
long[] res = solution(arr, p);
System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
}
CD36 数组的 partition 调整
public class CD36_1
{
public static int[] solution(int[] arr)
{
int idx = -1;
for (int i = 0; i < arr.length; i++)
{
if (idx == -1 || arr[i] != arr[idx])
{
idx++;
int temp = arr[i];
arr[i] = arr[idx];
arr[idx] = temp;
}
}
return arr;
}
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[] res = solution(arr);
System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
}
CD37 数组的 partition 调整(补充)
public class CD37_1
{
public static int[] solution(int[] arr)
{
int index = 0, small = -1, big = arr.length;
while (index < big)
{
if (arr[index] == 0) swap(arr, ++small, index++);
else if (arr[index] == 2) swap(arr, --big, index);
else index++;
}
return arr;
}
public static void swap(int[] arr, int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
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[] res = solution(arr);
System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
}
CD38 求最短通路值
public class CD38_1
{
public static int solution(String[] arr)
{
int n = arr.length - 1, m = arr[0].length() - 1;
boolean[][] vis = new boolean[n + 1][m + 1];
int[][] oris = new int[][]{{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
Queue<int[]> que = new LinkedList<>();
que.add(new int[]{0, 0, 1});
while (!que.isEmpty())
{
int[] pollNode = que.poll();
if (pollNode[0] == n && pollNode[1] == m) return pollNode[2];
for (int[] ori : oris)
{
int nextX = pollNode[0] + ori[0], nextY = pollNode[1] + ori[1];
if (nextX < 0 || nextX > n || nextY < 0 || nextY > m || vis[nextX][nextY] || '0' == arr[nextX].charAt(nextY))
continue;
que.add(new int[]{nextX, nextY, pollNode[2] + 1});
vis[nextX][nextY] = true;
}
}
return -1;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, m;
n = in.nextInt();
m = in.nextInt();
in.nextLine();
String[] arr = new String[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextLine();
System.out.println(solution(arr));
}
}
CD39 数组中未出现的最小正整数⭐
/*⭐*/
public class CD39_1
{
public static int solution(int[] arr)
{
int l = 0, r = arr.length;
while (l < r)
{
if (arr[l] == l + 1)
l++;
else if (arr[l] <= l || arr[l] > r || arr[l] == arr[arr[l] - 1])
arr[l] = arr[--r];
else
swap(arr, l, arr[l] - 1);
}
return l + 1;
}
public static void swap(int[] arr, int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
in.nextLine();
String[] s = in.nextLine().split(" ");
int[] arr = Arrays.stream(s).mapToInt(Integer::parseInt).toArray();
System.out.println(solution(arr));
}
}
CD40 数组排序之后相邻数的最大差值
/* 桶排序 */
public class CD40_1
{
public static int solution(int[] nums)
{
if (nums == null || nums.length < 2) return 0;
int len = nums.length;
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < len; i++)
{
min = Math.min(min, nums[i]);
max = Math.max(max, nums[i]);
}
if (min == max) return 0;
boolean[] hasNum = new boolean[len + 1];
int[] maxs = new int[len + 1];
int[] mins = new int[len + 1];
int bid = 0;
for (int i = 0; i < len; i++)
{
bid = bucket(nums[i], len, min, max);
mins[bid] = hasNum[bid] ? Math.min(mins[bid], nums[i]) : nums[i];
maxs[bid] = hasNum[bid] ? Math.max(maxs[bid], nums[i]) : nums[i];
hasNum[bid] = true;
}
int res = 0;
int lastMax = maxs[0];
int i = 1;
for (; i <= len; i++)
{
if (hasNum[i])
{
res = Math.max(res, mins[i] - lastMax);
lastMax = maxs[i];
}
}
return res;
}
public static int bucket(long num, long len, long min, long max)
{
return (int) ((num - min) * len / (max - min));
}
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();
System.out.println(solution(arr));
}
}
CD50 做项目的最大收益问题⭐
/*⭐模拟⭐*/
public class CD50_1
{
public static long solution(int w, int k, int[] costs, int[] profits)
{
PriorityQueue<int[]> costMin = new PriorityQueue<>((o1, o2) -> o1[0] - o2[0]);
PriorityQueue<int[]> profitMax = new PriorityQueue<>((o1, o2) -> o2[1] - o1[1]);
long ans = w;
for (int i = 0; i < costs.length; i++)
costMin.add(new int[]{costs[i], profits[i]});
while (k-- > 0)
{
while (!costMin.isEmpty() && ans >= costMin.peek()[0])
profitMax.add(costMin.poll());
if (!profitMax.isEmpty())
ans += profitMax.poll()[1];
}
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, w, k;
n = in.nextInt();
w = in.nextInt();
k = in.nextInt();
int[] costs = new int[n];
int[] profits = new int[n];
for (int i = 0; i < n; i++)
costs[i] = in.nextInt();
for (int i = 0; i < n; i++)
profits[i] = in.nextInt();
System.out.println(solution(w, k, costs, profits));
}
}
CD51 分金条的最小花费
public class CD51_1
{
public static long solution(int[] arr)
{
PriorityQueue<Long> que = new PriorityQueue<>();
long ans = 0;
for (int num : arr)
que.add((long) num);
while (que.size() != 1)
{
long t = que.poll() + que.poll();
ans += t;
que.add(t);
}
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n;
n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr));
}
}
CD52 大楼轮廓问题⭐
/*⭐*/
public class CD52_1
{
public static class Node implements Comparable<Node>
{
public int x;
public int h;
public boolean isAdd;
public Node(int x, boolean isAdd, int h)
{
this.x = x;
this.isAdd = isAdd;
this.h = h;
}
@Override
public int compareTo(Node o)
{
if (this.x != o.x)
return this.x - o.x;
if (this.isAdd != o.isAdd)
return this.isAdd ? -1 : 1;
return 0;
}
}
public static void solution(int[][] arr)
{
Node[] arrNode = new Node[arr.length * 2];
for (int i = 0; i < arr.length; i++)
{
arrNode[i * 2] = new Node(arr[i][0], true, arr[i][2]);
arrNode[i * 2 + 1] = new Node(arr[i][1], false, arr[i][2]);
}
Arrays.sort(arrNode);
TreeMap<Integer, Integer> heightMap = new TreeMap<>();
TreeMap<Integer, Integer> xMap = new TreeMap<>();
for (Node node : arrNode)
{
if (node.isAdd)
heightMap.put(node.h, heightMap.getOrDefault(node.h, 0) + 1);
else
{
if (heightMap.get(node.h) == 1)
heightMap.remove(node.h);
else
heightMap.put(node.h, heightMap.get(node.h) - 1);
}
if (heightMap.isEmpty())
xMap.put(node.x, 0);
else
xMap.put(node.x, heightMap.lastKey());
}
int s = -1, h = 0;
Set<Integer> key = xMap.keySet();
for (int x : key)
{
int t = xMap.get(x);
if (h != t)
{
if (h != 0)
System.out.println(s + " " + x + " " + h);
s = x;
h = t;
}
}
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[][] arr = new int[n][3];
for (int i = 0; i < n; i++)
for (int j = 0; j < 3; j++)
arr[i][j] = in.nextInt();
solution(arr);
}
}
CD53 加油站良好出发点问题❗
/*❗*/
public class CD53_1
{
public static boolean[] solution(int[] dis, int[] oil)
{
if (dis == null || oil == null || dis.length < 2 || dis.length != oil.length) return null;
int init = changeDisArrayGetInit(dis, oil);
return init == -1 ? new boolean[dis.length] : enlargeArea(dis, init);
}
public static int changeDisArrayGetInit(int[] dis, int[] oil)
{
int init = -1;
for (int i = 0; i < dis.length; i++)
{
dis[i] = oil[i] - dis[i];
if (dis[i] >= 0)
init = i;
}
return init;
}
public static boolean[] enlargeArea(int[] dis, int init)
{
boolean[] res = new boolean[dis.length];
int start = init;
int end = nextIndex(init, dis.length);
long need = 0;
long rest = 0;
do
{
if (start != init && start == lastIndex(end, dis.length)) break;
if (dis[start] < need) need -= dis[start];
else
{
rest += dis[start] - need;
need = 0;
while (rest >= 0 && end != start)
{
rest += dis[end];
end = nextIndex(end, dis.length);
}
if (rest >= 0)
{
res[start] = true;
connectGood(dis, lastIndex(start, dis.length), init, res);
break;
}
}
start = lastIndex(start, dis.length);
}
while (start != init);
return res;
}
public static void connectGood(int[] dis, int start, int init, boolean[] res)
{
long need = 0;
while (start != init)
{
if (dis[start] < need)
need -= dis[start];
else
{
res[start] = true;
need = 0;
}
start = lastIndex(start, dis.length);
}
}
public static int lastIndex(int index, int size)
{
return index == 0 ? (size - 1) : index - 1;
}
public static int nextIndex(int index, int size)
{
return index == size - 1 ? 0 : (index + 1);
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] oils = new int[n];
int[] diss = new int[n];
for (int i = 0; i < n; i++)
oils[i] = in.nextInt();
for (int i = 0; i < n; i++)
diss[i] = in.nextInt();
boolean[] res = solution(diss, oils);
for (boolean f : res)
if (f) System.out.print("1 ");
else System.out.print("0 ");
}
}
CD54 容器盛水问题⭐
/*⭐*/
public class CD54_1
{
public static long solution(int[] arr)
{
if (arr == null || arr.length < 3) return 0;
int[] leftMaxs = new int[arr.length];
leftMaxs[0] = arr[0];
for (int i = 1; i < arr.length; i++)
leftMaxs[i] = Math.max(leftMaxs[i - 1], arr[i]);
int[] rightMaxs = new int[arr.length];
rightMaxs[arr.length - 1] = arr[arr.length - 1];
for (int i = arr.length - 2; i >= 0; i--)
rightMaxs[i] = Math.max(rightMaxs[i + 1], arr[i]);
long res = 0;
for (int i = 1; i < arr.length - 1; i++)
res += Math.max(Math.min(leftMaxs[i - 1], rightMaxs[i + 1]) - arr[i], 0);
return res;
}
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();
System.out.println(solution(arr));
}
}
/*单调栈*/
public class CD54_2
{
public static long solution(int[] arr)
{
Stack<Integer> stack = new Stack<>();
long ans = 0;
for (int i = 0; i < arr.length; i++)
{
while (!stack.isEmpty() && arr[i] > arr[stack.peek()])
{
int top = stack.pop();
if (stack.isEmpty()) break;
int left = stack.peek();
ans += (i - left - 1L) * (Math.min(arr[left], arr[i]) - arr[top]);
}
stack.add(i);
}
return ans;
}
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();
System.out.println(solution(arr));
}
}
public class CD54_3
{
public static long solution(int[] arr)
{
if (arr == null || arr.length < 3) return 0;
long res = 0;
int leftMax = arr[0];
int rightMax = arr[arr.length - 1];
int L = 1;
int R = arr.length - 2;
while (L <= R)
{
if (leftMax <= rightMax)
{
res += Math.max(0, leftMax - arr[L]);
leftMax = Math.max(leftMax, arr[L++]);
}
else
{
res += Math.max(0, rightMax - arr[R]);
rightMax = Math.max(rightMax, arr[R--]);
}
}
return res;
}
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();
System.out.println(solution(arr));
}
}