康复训练一周吧还是省一,本来想国赛摆烂的但没想到延期了,还是准备一下吧,顺便记录一下省赛题解
A 星期计算
用前几个20幂来计算看一下可以发现取余结果是6和1摆动的,22次幂则为1,加1天则是星期日 或者用BigInteger硬算也可以
7
B 山
常规遍历题,读懂题目就好 可以先判断回文,再判断一端是否向中间单调不减
3138
C 字符统计
水题,直接桶排序输出即可
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Scanner;
public class Main {
static Scanner tab = new Scanner(System.in);
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static int N = 100010;
public static void main(String[] args) {
String s = tab.next();
int a[] = new int [30];
for(int i =0 ;i < s.length();i++) {
int t = s.charAt(i) - 'A';
a[t] ++ ;
}
int max = 0;
for(int i = 0; i< 30;i++) {
max =Math.max(max, a[i]);
}
for(int i = 0; i< 30 ;i++) {
if(a[i] == max) {
System.out.print((char)(i + (int)'A'));
}
}
}
}
D 最少刷题数
对于每个同学来说,排序后找到他的刷题数在序列中的位置,由于刷题数可以重复因此需要找到这个数的左右端点,那么就可以得到刷题数比他多和比他少的同学数量,即可计算出还需再刷多少题 为了简化搜素时间用了二分来查找左右端点
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static Scanner tab = new Scanner(System.in);
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static int N = 100010;
static int n;
static int a[] = new int[N];
static int b[] = new int[N];
static int findl(int x, int l, int r) {
if (l > r) {
return -1;
}
int mid = (l + r) / 2;
if (b[mid] == x) {
if (mid - 1 >= 0) {
if (b[mid - 1] != x) {
return mid;
} else {
return findl(x, l, mid - 1);
}
} else {
return 0;
}
} else if (b[mid] < x) {
return findl(x, mid + 1, r);
} else {
return findl(x, l, mid - 1);
}
}
static int findr(int x, int l, int r) {
if (l > r) {
return -1;
}
int mid = (l + r + 1) / 2;
if (b[mid] == x) {
if (mid + 1 <= n - 1) {
if (b[mid + 1] != x) {
return mid;
} else {
return findr(x, mid + 1, r);
}
} else {
return n - 1;
}
} else if (b[mid] < x) {
return findr(x, mid + 1, r);
} else {
return findr(x, l, mid - 1);
}
}
public static void main(String[] args) throws IOException {
n = tab.nextInt();
String s[] = br.readLine().split(" ");
for (int i = 0; i < n; i++) {
a[i] = Integer.parseInt(s[i]);
b[i] = a[i];
}
Arrays.sort(b, 0, n);
for (int i = 0; i < n; i++) {
int indexl = findl(a[i], 0, n - 1);
int indexr = findr(a[i], 0, n - 1);
int numl = indexl;
int numr = n - 1 - indexr;
int cnt = 0;
if (numr > numl) {
int t = (numr - numl + 1) / 2;
cnt = b[indexr + t] - b[indexr] + 1;
}
if (i == 0) {
bw.write(cnt + "");
} else {
bw.write(" " + cnt);
}
}
bw.flush();
bw.close();
}
}
E 求阶乘
暴力使用int或long都是肯定会爆的,可以先算几组答案找出规律 用BigInteger算个几百上千的阶乘不成问题,总结一下就能找出规律,考场脑抽用了long算的样例太少规律找错了,代码就不贴了🏃
F 最大子矩阵
用前缀和线段树尝试无果,只好狠狠地暴力了😑
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static Scanner tab = new Scanner(System.in);
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static int N = 100010;
static int a[][] = new int[90][100010];
static int inf = 999999;
public static void main(String[] args) throws IOException {
String s1[] = br.readLine().split(" ");
int n = Integer.parseInt(s1[0]);
int m = Integer.parseInt(s1[1]);
for (int i = 0; i < n; i++) {
String s2[] = br.readLine().split(" ");
for (int j = 0; j < m; j++) {
a[i][j] = Integer.parseInt(s2[j]);
}
}
int limit = Integer.parseInt(br.readLine());
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
for (int u = i ; u < n; u++) {
for (int v = j ; v < m; v++) {
int max = 0;
int min = inf;
for(int k = i; k<=u;k++) {
for(int p = j; p <= v ;p++) {
max = Math.max(max, a[k][p]);
min = Math.min(min, a[k][p]);
}
}
int f = max - min;
if(f <= limit) {
int ans = (u-i+1) * (v-j+1);
res = Math.max(res, ans);
}
}
}
}
}
System.out.println(res);
}
}
G 数组切分
没想到什么优化方法,继续暴力 用了一个二进制枚举
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static Scanner tab = new Scanner(System.in);
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static int N = 10010;
static int a[] = new int [N];
static int t[] = new int [N];
static int cnt = 0;
static boolean check() {
Arrays.sort(t, 0, cnt);
if(t[0] + cnt -1 != t[cnt-1]) {
return false;
}
return true;
}
public static void main(String[] args) throws IOException {
int n = tab.nextInt();
for(int i = 0; i< n; i++) {
a[i] = tab.nextInt();
}
long res = 0;
for(long op = 0; op < 2 << (n-2) ; op++) {
cnt = 0;
boolean flag = true;
String s = Long.toBinaryString(op);
while(s.length() < n-1) {
s = "0" + s;
}
for(int i = 0; i < n; i++) {
t[cnt++] = a[i];
if(i == n-1) {
if(!check()) {
flag = false;
}
break;
}
if(s.charAt(i) == '1') {
if(!check()) {
flag = false;
break;
}
cnt = 0;
}
}
if(flag) {
res += 1;
}
}
System.out.println(res % 1000000007);
}
}
H 回忆迷宫
纯纯的看题干=看小说
I 红绿灯
小说 I
J 拉箱子
小说 J
总结一下就是难度跟模拟赛对比好像在逗我
还有我们Java的BigInteger真是太好用辣😆
|