7题金,6题银,5题铜
【参考:2021-2022年度第三届全国大学生算法设计与编程挑战赛(冬季赛)题解_int 我的博客-CSDN博客】
【参考:2021-2022年度第三届全国大学生算法设计与编程挑战赛 【部分题题解】_辉小歌的博客-CSDN博客】
签到题:模拟,程序填空(I题)
容易题:E、G、K
练习网址:
http://vj.saikr.com/contest/20/problem/D
D为题目序号
题目列表:http://vj.saikr.com/contest/20/problems
B: Error
思路:二分
import java.util.Scanner;
// 参考:https://blog.csdn.net/m0_58177653/article/details/123773699
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
int low = 0;
int high = Integer.MAX_VALUE;
int result = -1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (check(mid, a)) {
// 存在,要求求最小的eps,缩小右区间
result = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
System.out.println(result);
}
// 存在题目要求的序列b_i 返回true 否则为false
// b_i为上升正整数序列,对于任意i都有|a_i-b_i|<=eps
public static boolean check(int eps, int[] a) {
int n = a.length;
int b = Math.max(1, a[0] - eps); // b_0
// System.out.println(b);
for (int i = 1; i < n; i++) {
if (a[i] + eps < b + 1) // b_i+1至少为b_i+1
return false; // 二者差值大于eps
else { // a[i]和b_i+1 二者差值<= eps
// b_i+1至少为b_i+1, b_i+1最小为a[i]-eps 二者取最大值
b = Math.max(b + 1, a[i] - eps);
// System.out.println(b);
}
// a:7 9 5 1 3 2
// b:1 3 4 5 6 7
}
return true;
}
}
n = int(input())
a = [int(i) for i in input().strip().split()]
l=0
r = max(a)-min(a)
result =0
def check(mid):
b = max(a[0]-mid,1)
for i in a[1:]:
if i+mid<b+1:
return False
else:
b=max(b+1,i-mid)
return True
while l<=r:
mid =int((l+r)/2)
if check(mid):
result = mid
r = mid-1
else:
l = mid+1
print(result)
D: 树的果实 不会
【参考:saikr oj | 树的果实】
好像是区间查询,但和树在一起就不会了
E: 吃利息(签到题)
【参考:saikr oj | 吃利息】
简单模拟题
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int k = sc.nextInt();
int n = sc.nextInt();
int result = k;
for (int i = 1; i <= n; i++) {
int x = result / 10;
// 利息
if (x >= 5)
result += 5;
else
result += x;
result += 5;
}
System.out.println(result);
}
}
F:Star
【参考:saikr oj | F:Star】
凸包
G: MP4
【参考:saikr oj | MP4】
【参考:第三届全国大学生算法设计与编程挑战赛 (冬季赛)部分题解_容艾的博客-CSDN博客】
Input
一行一个数字 n, 表示存在的视频个数
Output
一共 50 行,每行一个字符串,分别为字典序第 i 小的视频文件名,注意,这个文件名里需要包含 .mp4
暴力法,超时 大概能到1000000
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String[] arr = new String[n];
for (int i = 0; i < n; i++) {
arr[i] = String.valueOf(i+1);
}
// 字典序排序
Arrays.sort(arr, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
for (int i = 0; i < 50; i++) {
System.out.println(arr[i]+".mp4");
}
}
}
【参考:2021-2022年度第三届全国大学生算法设计与编程挑战赛(冬季赛)G. MP4_NEFU AB-IN的博客-CSDN博客】
dfs爆搜即可
- dfs(l, r, k) 表示边界为l,r,找k个
- 举个例子n = 100 n = 100n=100
- 优先考虑大的数,所以10倍扩大范围(因为0是最优的),直到不能扩了,如1 , 10 , 100 1, 10, 1001,10,100
- 其次开始在l , r l, rl,r中枚举,如11 , 12 , . . . 19 11,12,…1911,12,…19
- 当到了10的倍数时(比如20),意味着此位数字换了,也就是此位数字为x 的数枚举完了,return即可
有点不太好理解
import java.util.Scanner;
public class Main {
static int n;
static int sum = 0; // 枚举个数
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
dfs(1, 9, 50);
}
// 在[left,right]中找k个数 k=50
// 1<=left<right<=n
// left,right只相差一位数,如100,999
public static void dfs(int left, int right, int k) {
if (right > n) right = n; // 防止越界
for (int i = left; i <= right; i++) { // 遍历[left,right]
if (i != left && i % 10 == 0) // 比如left:10,right:99,i只需要遍历10-19就行了
return; // 该位枚举完毕
sum++;
if (sum <= k) {
System.out.println(i + ".mp4");
if (sum == k) return;
}
if (i * 10 <= n)
// 都增加一位
dfs(i * 10, i * 100 - 1, k);
}
}
}
I:展览(线性基)
【参考:saikr oj | 展览】
考点:线性基
没看懂
K:礼物
【参考:saikr oj | 礼物】
签到题
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr=new int[n];
for (int i = 0; i < n; i++) {
arr[i]=sc.nextInt();
}
Arrays.sort(arr);
System.out.println(arr[n-1]);
}
}
L: 看错题 不会
线段树