排序问题
【深基9.例4】求第 k 小的数
题目描述
输入 n n n( 1 ≤ n < 5000000 1 \le n < 5000000 1≤n<5000000 且 n n n 为奇数)个数字 a i a_i ai( 1 ≤ a i < 10 9 1 \le a_i < {10}^9 1≤ai<109),输出这些数字的第 k k k 小的数。最小的数是第 0 0 0 小。
请尽量不要使用 nth_element
来写本题,因为本题的重点在于练习分治算法。
输入格式
输出格式
样例 #1
样例输入 #1
5 1
4 3 2 1 5
样例输出 #1
2
代码如下:
我的第一版代码60分,两个点超时!
java
package exercise.luogu.sort.two;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;
public class P1923 {
static int[] nums;
static int k;
public static void main(String[] args) throws Exception {
Read sc = new Read();
int n = sc.nextInt();
k = sc.nextInt();
nums = new int[n];
for (int i = 0; i < nums.length; i++) {
nums[i] = sc.nextInt();
}
Arrays.sort(nums);
System.out.println(nums[k]);
}
}
class Read {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public int nextInt() throws Exception {
st.nextToken();
return (int) st.nval;
}
}
java
package exercise.luogu.sort.two;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;
public class P1923 {
static int[] nums;
static int k;
public static void main(String[] args) throws Exception {
Read sc = new Read();
int n = sc.nextInt();
k = sc.nextInt();
nums = new int[n];
for (int i = 0; i < nums.length; i++) {
nums[i] = sc.nextInt();
}
quickSort(nums, 0, n - 1);
System.out.println(nums[k]);
}
public static void quickSort(int q[], int l, int r) {
if (l >= r)
return;
int pivot = q[l];
int i = l, j = r;
while (i < j) {
while (i < j && q[j] >= pivot) {
j--;
}
while (i < j && q[i] <= pivot) {
i++;
}
if (i < j) {
int temp = q[i];
q[i] = q[j];
q[j] = temp;
}
}
q[l] = q[i];
q[i] = pivot;
if (i == k) return;
if (i > k)
quickSort(q, l, i - 1);
else if (i < k)
quickSort(q, i + 1, r);
}
}
class Read {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public int nextInt() throws Exception {
st.nextToken();
return (int) st.nval;
}
}
贪心问题
小A的糖果
题目描述
小 A 有 n n n 个糖果盒,第 i i i 个盒中有 a i a_i ai 颗糖果。
小 A 每次可以从其中一盒糖果中吃掉一颗,他想知道,要让任意两个相邻的盒子中糖的个数之和都不大于 x x x,至少得吃掉几颗糖。
输入格式
输入的第一行是两个用空格隔开的整数,代表糖果盒的个数 n n n 和给定的参数 x x x。
第二行有 n n n 个用空格隔开的整数,第 i i i 个整数代表第 i i i 盒糖的糖果个数 a i a_i ai。
输出格式
输出一行一个整数,代表最少要吃掉的糖果的数量。
样例 #1
样例输入 #1
3 3
2 2 2
样例输出 #1
1
样例 #2
样例输入 #2
6 1
1 6 1 2 0 4
样例输出 #2
11
样例 #3
样例输入 #3
5 9
3 1 4 1 5
样例输出 #3
0
提示
样例输入输出 1 解释
吃掉第 2 盒中的一个糖果即可。
样例输入输出 2 解释
第 2 盒糖吃掉 6 6 6 颗,第 4 盒吃掉 2 2 2 颗,第 6 盒吃掉 3 3 3 颗。
数据规模与约定
- 对于 30 % 30\% 30% 的数据,保证 n ≤ 20 n \leq 20 n≤20, a i , x ≤ 100 a_i, x \leq 100 ai,x≤100。
- 对于 70 % 70\% 70% 的数据,保证 n ≤ 1 0 3 n \leq 10^3 n≤103, a i , x ≤ 1 0 5 a_i, x \leq 10^5 ai,x≤105。
- 对于 100 % 100\% 100% 的数据,保证 2 ≤ n ≤ 1 0 5 2 \leq n \leq 10^5 2≤n≤105, 0 ≤ a i , x ≤ 1 0 9 0 \leq a_i, x \leq 10^9 0≤ai,x≤109。
我自己过不了,就过了两个点
java
package exercise.luogu.greedy;
import java.util.Scanner;
public class P3817 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 数组长度
int x = sc.nextInt(); // 目标值
int[] nums = new int[n];
// 读取数组元素
for (int i = 0; i < n; i++) {
nums[i] = sc.nextInt();
}
int count = 0; // 用于计算超过x的部分的总和
// 遍历数组,检查相邻的两个数的和是否大于x
for (int i = 0; i < n - 1; i++) {
if (nums[i] + nums[i + 1] > x) {
// 计算超过x的部分,并累加到count中
count += nums[i] + nums[i + 1] - x;
// 可选:减少较大的那个数,使其和不超过x
if (nums[i] > nums[i + 1]) {
nums[i] -= (nums[i] + nums[i + 1] - x);
} else {
nums[i + 1] -= (nums[i] + nums[i + 1] - x);
}
}
}
// 输出结果
System.out.println(count);
}
}
真的好难啊!