第十四届蓝桥杯三月真题刷题训练——第 3 天
题目1:门牌制作
数据范围不大,模拟即可
import java.util.*;
import java.math.*;
import java.io.*;
public class Main {
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
// static StreamTokenizer st = new StreamTokenizer(in);
static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
public static void main(String[] args) throws Exception {
int cnt = 0;
for (int i = 1; i <= 2020; i++) {
int t = i;
while (t > 0) {
cnt += (t % 10 == 2)? 1: 0;
t /= 10;
}
}
out.println(cnt);
out.flush();
in.close();
}
}
题目2:货物摆放
如果a * b * c = d
,那么 a、b、c 肯定是 d 的因子,因此可以先预处理出所有的因子,然后枚举所有的可能性即可。
import java.util.*;
import java.math.*;
import java.io.*;
public class Main {
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
// static StreamTokenizer st = new StreamTokenizer(in);
static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
static long num = 2021041820210418L;
public static void main(String[] args) throws Exception {
List<Long> list = new ArrayList<>();
long cnt = 0, end = (long)Math.sqrt(num);
for (long i = 1; i <= end; i++) {
if (num % i == 0) {
list.add(i);
if (num / i != i) list.add(num / i);
}
}
int sz = list.size();
for (long a: list) {
for (long b: list) {
for (long c: list) {
if (a * b * c == num) cnt++;
}
}
}
out.println(cnt);
out.flush();
in.close();
}
}
题目3:跳跃
动态规划
f[i][j]
为从(1, 1)
点出发到 (i, j)
的最大权值。
到达当前点一共可以从以上九种状态转移过来,从不越界的方案中选择权值最大的即可。
import java.util.*;
import java.math.*;
import java.io.*;
public class Main {
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
// static StreamTokenizer st = new StreamTokenizer(in);
static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
static int N = 110, n, m;
static int[][] a = new int[N][N], f = new int[N][N];
static int[] dx = {0, 0, 0, -1, -1, -1, -2, -2, -3};
static int[] dy = {-1, -2, -3, 0, -1, -2, 0, -1, 0};
public static void main(String[] args) throws Exception {
// input...
String[] nm = in.readLine().split(" ");
n = Integer.parseInt(nm[0]);
m = Integer.parseInt(nm[1]);
for (int i = 1; i <= n; i++) {
String[] s = in.readLine().split(" ");
for (int j = 1; j <= m; j++) {
a[i][j] = Integer.parseInt(s[j - 1]);
}
}
for (int i = 0; i <= n; i++) Arrays.fill(f[i], -100000);
f[1][1] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
// 状态转移
for (int k = 0; k < 9; k++) {
int nx = i + dx[k], ny = j + dy[k];
if (nx <= 0 || nx > n || ny <= 0 || ny > m || f[nx][ny] == -100000) continue;
f[i][j] = Math.max(f[i][j], f[nx][ny]);
}
f[i][j] += a[i][j];
}
}
out.println(f[n][m]);
out.flush();
in.close();
}
}
题目4:重新排序
前缀和 + 差分 + 贪心
查询次数越多的位置放的数越大越好
import java.util.*;
import java.math.*;
import java.io.*;
public class Main {
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
// static StreamTokenizer st = new StreamTokenizer(in);
static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
static int N = (int)1e5 + 10, n, m;
// a:原数组
// pre:前缀和数组
// diff:差分数组
static long[] a = new long[N], pre = new long[N], diff = new long[N];
// 区间[x, y] + 1
public static void insert(int x, int y) {
diff[x] += 1;
diff[y + 1] -= 1;
}
public static void main(String[] args) throws Exception {
n = Integer.parseInt(in.readLine());
String[] s = in.readLine().split(" ");
for (int i = 1; i <= n; i++) {
a[i] = Integer.parseInt(s[i - 1]);
pre[i] = pre[i - 1] + a[i];
}
m = Integer.parseInt(in.readLine());
// preSum:原数组的累加和
long preSum = 0L;
while (m-- > 0) {
String[] ab = in.readLine().split(" ");
int a = Integer.parseInt(ab[0]), b = Integer.parseInt(ab[1]);
preSum += pre[b] - pre[a - 1];
insert(a, b);
}
for (int i = 1; i <= n; i++) {
diff[i] += diff[i - 1];
}
Arrays.sort(diff, 1, n + 1);
Arrays.sort(a, 1, n + 1);
long sum = 0L;
for (int i = n; i >= 1; i--) {
sum += a[i] * diff[i];
}
out.println(sum - preSum);
out.flush();
in.close();
}
}