试题链接:链接
A题
满足条件的答案有:35813116
public class TianShu {
public static void main(String[] args) {
int ans = 0;
// 2000.1.1 - 2000000.1.1
// 年份是月份的倍数,也是日的倍数
for (int year=2000; year<=2000000; year++) {
for (int month=1; month<=12; month++) {
if (month == 2) {
for (int day=1; day<=28; day++) {
if (year % month == 0 && year % day == 0) {
ans++;
}
}
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { // 闰年补一个2月29日
if (year % month == 0 && year % 29 == 0) {
ans++;
}
}
} else if (month == 1 || month ==3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
for (int day=1; day<=31; day++) {
if (year % month == 0 && year % day == 0) {
ans++;
}
}
} else {
for (int day=1; day<=30; day++) {
if (year % month == 0 && year % day == 0) {
ans++;
}
}
}
}
}
System.out.println("满足条件的答案有:" + ans);
}
}
B题
public class LogicGateSimulation {
public static void main(String[] args) {
// 定义输入数组
int[] input = {1, 0, 1, 0, 1};
// 数组用于储存中间结果
int[][] arr = new int[5][5];
// 初始化输入
for (int i = 0; i < 5; i++) {
arr[0][i] = input[i];
}
// 计算每一层的结果,并统计满足条件的组合数量
int count = calculateGatesHelper(arr, 1);
System.out.println("满足条件的组合数量: " + count);
}
// 参数含义:
// arr 用于存储中间结果的数组
// layer 当前处理的层数
private static int calculateGatesHelper(int[][] arr, int layer) {
// 递归终止条件:到达最后一层
if (layer == arr.length) {
// 判断最后的输出值是否为1
return arr[layer - 1][0] == 1 ? 1 : 0;
}
int totalCombinations = 0; // 用于统计满足条件的组合数量
// 遍历所有可能的逻辑门(AND、OR、XOR)
for (int gate = 0; gate < 3; gate++) {
// 遍历当前层的所有列数(有效列数为 5 - layer)
for (int i = 0; i < (5 - layer); i++) {
// 根据逻辑门类型计算
switch (gate) {
case 0: // AND 门
arr[layer][i] = arr[layer - 1][i] & arr[layer - 1][i + 1];
break;
case 1: // OR 门
arr[layer][i] = arr[layer - 1][i] | arr[layer - 1][i + 1];
break;
case 2: // XOR 门
arr[layer][i] = arr[layer - 1][i] ^ arr[layer - 1][i + 1];
break;
}
}
// 递归处理下一层
totalCombinations += calculateGatesHelper(arr, layer + 1);
}
return totalCombinations; // 返回满足条件的组合数量
}
}
C题
import java.util.Arrays;
import java.util.Scanner;
public class QiPan {
public static void main(String[] args) {
// 二维数组操作
Scanner scanner = new Scanner(System.in);
// 棋盘大小 和 操作数
int len = scanner.nextInt();
int[][] qipan = new int[len][len];
int operationNum = scanner.nextInt();
// 操作
for (int i=0; i<operationNum; i++) {
int x1 = scanner.nextInt() - 1;
int y1 = scanner.nextInt() - 1;
int x2 = scanner.nextInt() - 1;
int y2 = scanner.nextInt() - 1;
// 做操作
for (int j = x1; j <= x2; j++) {
for (int k = y1; k <=y2; k++) {
qipan[j][k] = qipan[j][k] == 0 ? 1 : 0; // 取反
}
}
}
for (int i=0; i<len; i++) {
for (int j=0; j<len; j++) {
System.out.print(qipan[i][j]);
}
System.out.println();
}
}
}
D题
import com.sun.xml.internal.bind.v2.runtime.reflect.opt.Const;
import java.util.Scanner;
public class ZiJuZhen {
public static void main(String[] args) {
int modNum = 998244353;
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
int n = scanner.nextInt();
int a = scanner.nextInt();
int b = scanner.nextInt();
int[][] matrix = new int[m][n];
for (int i=0; i<m; i++) {
for (int j=0; j<n; j++) {
matrix[i][j] = scanner.nextInt();
}
}
int ans = 0;
// 方法一 暴力穷举所有 a * b 的子数组
for (int i=0; i <= (m - a); i++) {
for (int j=0; j <= (n - b); j++) {
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int k=0; k < a; k++) {
for (int q=0; q < b; q++) {
min = Math.min(min, matrix[i+k][j+q]);
max = Math.max(max, matrix[i+k][j+q]);
}
}
ans += min*max;
}
}
System.out.println("价值为 :" + ans%modNum);
}
}
试题 E
import java.util.Scanner;
public class HuZhiShu {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long a = sc.nextLong();
long b = sc.nextLong();
long ans = 0;
long num = (long) Math.pow(a, b);
for (int i=1; i<num; i++) {
if (gcd(i,num) == 1) {
ans++;
}
}
System.out.println("结果为:" + ans % 998244353);
}
public static long gcd(long a, long b){
if(a == 0){
return b;
} else {
return gcd(b % a, a);
}
}
}
试题F
import java.util.PriorityQueue;
import java.util.Scanner;
public class TravelPlan {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 输入n和m,n为地点数,m为油箱最大容量
int n = sc.nextInt();
int m = sc.nextInt();
// 定义三个数组,分别存储距离Dis、加油费用Cost、加油上限Lim
int[] Dis = new int[n];
int[] Cost = new int[n];
int[] Lim = new int[n];
for (int i = 0; i < n; i++) {
Dis[i] = sc.nextInt();
Cost[i] = sc.nextInt();
Lim[i] = sc.nextInt();
}
// 当前油量
int currentFuel = m;
// 当前花费
long totalCost = 0;
// 最小堆,用于存储当前可用的加油站 (按加油费用排序)
PriorityQueue<int[]> minHeap = new PriorityQueue<>((a, b) -> a[0] - b[0]);
// 遍历每个加油站
for (int i = 0; i < n; i++) {
if (i == 0) {
currentFuel -= Dis[0];
}
// 到达下一个加油站需要消耗的油量
if (i != n - 1) {
if (Dis[i + 1] > m) { // 需要的油量大于油箱容量,无法完成旅程
System.out.println("-1");
return;
}
currentFuel -= Dis[i + 1];
}
// 更新最小堆可加油量
minHeap.offer(new int[]{Cost[i], Lim[i]});
// 如果当前油量不足以到达下一站,需要从堆中加油
while (currentFuel < 0) {
// 如果堆为空,说明无油可加,无法完成旅程
if (minHeap.isEmpty()) {
System.out.println("-1");
return;
}
// 从堆中取出最便宜的加油站加油
int[] station = minHeap.poll();
int price = station[0];
int availableFuel = station[1];
// 需要补足的油量
int fuelNeeded = Math.min(-currentFuel, availableFuel);
totalCost += (long) fuelNeeded * price;
currentFuel += fuelNeeded;
// 更新加油站剩余可加油量
if (availableFuel > fuelNeeded) {
minHeap.offer(new int[]{price, availableFuel - fuelNeeded});
}
}
}
// 输出总费用
System.out.println(totalCost);
}
}
G题
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class StrangeNUM {
static int[] odds = {1,3,5,7,9};
static int[] evens = {0,2,4,6,8};
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// the length of this number
int n = scanner.nextInt();
// The sum of five consecutive digits is not greater than m
int m = scanner.nextInt();
// Requirement: Odd bits are odd, even bits are even
// the first bit - the last bit
List<String> result = new ArrayList<>();
getNum(n, "", result, m);
int ans = 0;
for (int i=0; i<result.size(); i++) {
if (isNotGreaterThanM(result.get(i), m)) {
ans++;
ans = ans % 998244352;
}
}
System.out.println("ans = " + ans);
}
public static void getNum(int n, String cur, List<String> result, int m){
// 当前数字长度为 n 时输出
if (cur.length() == n) {
result.add(cur);
return;
}
if (cur.length() % 2 == 0) { // 下一位是奇数
for (int bit : odds) {
if (bit <= m) {
getNum(n, cur + bit, result, m);
}
}
} else {
for (int bit: evens) {
if (bit <= m) {
getNum(n, cur + bit, result, m);
}
}
}
}
public static boolean isNotGreaterThanM(String num, int m){
// 滑动窗口
int sum = 0;
int left = -1;
int right = 0;
char[] numChar = num.toCharArray();
while (right < numChar.length) {
sum += Integer.parseInt(numChar[right] + "");
if (right - left == 5) {
if (sum > m) {
return false;
}
left++;
sum -= Integer.parseInt(numChar[left] + "");
}
right++;
}
return true;
}
}
第H题
import java.util.PriorityQueue;
import java.util.Scanner;
//6 10 10
//5 3 5
//6 2 4
//0 1 10
//2 11 3
//2 13 3
//2 15 5
//
public class Sun {
public static void main(String[] args) {
// 接收输入
Scanner sc = new Scanner(System.in);
// 线段个数
int n = sc.nextInt();
// 太阳坐标
int X = sc.nextInt();
int Y = sc.nextInt();
// 线段
// int[] y坐标 x1, x2
// 太阳上方按照 Y 从小到大排序
PriorityQueue<int[]> upPriorityQueue = new PriorityQueue<>((a, b) -> a[0] - b[0]);
// 太阳下方按照 Y 从大到小排序
PriorityQueue<int[]> downPriorityQueue = new PriorityQueue<>((a, b) -> b[0] - a[0]);
for (int i=0; i<n; i++) {
int[] line = new int[3];
line[1] = sc.nextInt();
line[0] = sc.nextInt();
line[2] = line[1] + sc.nextInt();
if (line[0] <= Y) {
downPriorityQueue.add(line);
} else {
upPriorityQueue.add(line);
}
}
int ans = 0;
// 判断遮挡
// 先假设没有两个线段在同一 y
// 遮挡范围
int[] shelter = {Integer.MAX_VALUE, Integer.MIN_VALUE};
while (!downPriorityQueue.isEmpty()) {
// 判断是否有遮挡
int[] curLine = downPriorityQueue.poll();
if (!(shelter[0] <= curLine[1] && shelter[1] >= curLine[2])) {
ans++;
}
// 更新 shelter
shelter[0] = Math.min(shelter[0], curLine[1]);
shelter[1] = Math.max(shelter[1], curLine[2]);
}
shelter = new int[]{Integer.MAX_VALUE, Integer.MIN_VALUE};
while (!upPriorityQueue.isEmpty()) {
// 判断是否有遮挡
int[] curLine = upPriorityQueue.poll();
if (!(shelter[0] <= curLine[1] && shelter[1] >= curLine[2])) {
ans++;
}
// 更新 shelter
shelter[0] = Math.min(shelter[0], curLine[1]);
shelter[1] = Math.max(shelter[1], curLine[2]);
}
System.out.println("结果为:" + ans);
}
}
// 上述思路只能解决 没有两个线段在同一 y 的情况
// 有两个线段在同一 y 的情况 —— 应该算透光部分解决 - 太麻烦了,不做