前前后后准备了快两个月,还算有所收获,国奖应该能拿个,不过感觉国赛的题比省赛简单的多就很迷
A 整数范围
签到,刚开始还以为有什么坑斟酌了半天
public static void main(String[] args) {
String s ="11111111";
int x = Integer.parseInt(s,2);
System.out.println(x);
}
255
B 纯质数![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/fa71312abb231bb72ec991e0d854c225.png)
常规题,欧拉筛出质数再遍历一遍判断即可,反正是填空怎么筛都行
package atta;
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static Scanner tab = new Scanner(System.in);
static int N = 30000010;
static int cnt = 0;
static int primes[] = new int [N];
static boolean st[] = new boolean [N];
static void get_primes(int n) {
for(int i = 2;i<=n;i++) {
if(!st[i]) {
primes[cnt++] = i;
}
for(int j = 0; primes[j]*i <=n;j++) {
int t = primes[j] *i;
st[t] = true;
if(i%primes[j] == 0)
break;
}
}
}
static int res = 0;
static int check() {
for(int i = 0;i<cnt;i++) {
String s = String.valueOf(primes[i]);
boolean flag = true;
for(int j = 0;j<s.length();j++) {
if(s.charAt(j) == '2' || s.charAt(j) == '3' || s.charAt(j) == '5' || s.charAt(j) == '7')
continue;
else {
flag = false;
break;
}
}
if(flag) {
res ++ ;
}
}
return res;
}
public static void main(String[] args) {
int n = 20210605;
get_primes(n);
System.out.println(cnt);
System.out.println();
int x=check();
System.out.println();
System.out.println(x);
}
}
1903
C 完全日期
这题刚刚好比赛前一天复习到了,用一个函数来判断日期合法性(日期问题总结),再判断是否符合标准即可
就是日期求和那里写的笨比了点,转成字符串来计算应该方便些
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static Scanner tab = new Scanner(System.in);
static int N = 30000010;
static boolean check(int y, int m, int d) {
String s = y + "-" + m + "-" + d;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setLenient(false);
try {
sdf.parse(s);
} catch (ParseException e) {
return false;
}
return true;
}
static boolean cal(int y, int m, int d) {
int ans = 0;
while (y > 0) {
int x = y % 10;
ans += x;
y /= 10;
}
while (m > 0) {
int x = m % 10;
ans += x;
m /= 10;
}
while (d > 0) {
int x = d % 10;
ans += x;
d /= 10;
}
int t = (int) Math.sqrt(ans);
if (t * t == ans)
return true;
return false;
}
public static void main(String[] args) {
int res = 0;
for (int i = 2001; i <= 2021; i++) {
for (int j = 1; j <= 12; j++) {
for (int k = 1; k <= 31; k++) {
if (check(i, j, k)) {
if (cal(i, j, k)) {
System.out.println(i + "-" + j + "-" + k);
res++;
}
}
}
}
}
System.out.println(res);
}
}
977
D 最小权值
原先思路是dfs求出所有树,再用递归计算每种树的权值取最小值,不过也就想到这,略了,应该是有随机生成树的算法不过没学过。。
E 大写
有被水到,还是怕有坑检查了半天
import java.io.*;
import java.text.*;
import java.util.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static Scanner tab = new Scanner(System.in);
static int N = 30000010;
public static void main(String[] args) {
String s = tab.next();
System.out.println(s.toUpperCase());
}
}
F 123
数据量很大,遍历必暴,所以先把数组压缩成每个元素是原数组从1开始到下一个1之间的值(1,3,6,10…),再通过输入的坐标转换为新数组坐标L R,将LR之间的完整区间段元素直接求和,最后再将LR两边缘不完整的元素累加上,求和部分为了缩短时间用了树状数组,回来想想又没有区间修改直接用前缀和不好么。。
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static Scanner tab = new Scanner(System.in);
static int N = 2000000;
static long w[] = new long[N+1];
static long tr[] = new long[N+1];
static int lowbit(int x) {
return x & -x;
}
static long query(int x) {
long res = 0;
for (int i = x; i >= 1; i -= lowbit(i)) {
res += tr[i];
}
return res;
}
static void add(int x, long v) {
for (int i = x; i <= N; i += lowbit(i)) {
tr[i] += v;
}
}
static void getw() {
for (int i = 1; i < N; i++) {
w[i] = w[i - 1] + i;
}
}
static int get(int x) {
for (int i = 1; i <= N; i++) {
if (x <= w[i])
return i;
}
return -1;
}
public static void main(String[] args) throws IOException {
getw();
for (int i = 1; i < N; i++) {
add(i, w[i]);
}
int m = tab.nextInt();
while (m-- > 0) {
String s = br.readLine();
int l = Integer.parseInt(s.split(" ")[0]);
int r = Integer.parseInt(s.split(" ")[1]);
long res = 0;
int a = get(l);
int b = get(r);
res += query(b - 1) - query(a);
long lr = w[a];
long rl = w[b] - b + 1;
int k = 0;
for(long i = lr-a+1; i<=lr; i++) {
k++;
if(l <= i) {
res += k;
}
}
k = 0;
for(long i = rl;i<=rl+b-1;i++) {
k++;
if(r>=i) {
res+=k;
}
}
System.out.println(res);
}
}
}
G 和与乘积
刚开始又想用树状数组改成乘积的形式,敲了一会反应过来之间前缀和改就好了 ==
不过判断double是否整数那里犹豫了一下,随便乘了个一百万再取余的希望不会爆
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static Scanner tab = new Scanner(System.in);
static int N = 200010;
static long w[] = new long[N + 1];
static long tr[] = new long[N + 1];
static long trr[] = new long[N + 1];
static int n;
public static void main(String[] args) throws IOException {
int res = 0;
Arrays.fill(trr, 1);
n = tab.nextInt();
for (int i = 1; i <= n; i++) {
w[i] = tab.nextLong();
tr[i] = tr[i-1] + w[i];
trr[i] = trr[i-1] * w[i];
}
for(int a =1;a<=n;a++) {
for(int b = a;b<=n;b++) {
long x = tr[b]-tr[a-1];
double y = (double)trr[b]/trr[a-1];
if(y*1000000%1000000 != 0)
continue;
if(x == y) {
res++;
}
}
}
System.out.println(res);
}
}
H 巧克力
没思路跳了,骗样例过
I 翻转括号序列
用栈的思想来找出最长合法序列,感觉是挺简单的也不知道有没有坑
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static Scanner tab = new Scanner(System.in);
static int N = 1000010;
public static void main(String[] args) throws IOException {
// 左(0 右)1
int n = tab.nextInt();
int m = tab.nextInt();
String s = " " + tab.next();
while (m-- > 0) {
int k = tab.nextInt();
if (k == 1) {
int l = tab.nextInt();
int r = tab.nextInt();
char c[] =s.toCharArray();
for(int i =l; i<=r;i++) {
if(c[i] == '(')
c[i] = ')';
else
c[i] = '(';
}
s = new String(c);
}
else {
int l = tab.nextInt();
Stack<Integer> stack = new Stack<>();
int res = 0;
for (int i = l; i < s.length(); i++) {
if (s.charAt(i) == '(') {
stack.push(0);
} else {
if (!stack.isEmpty()) {
if (stack.peek() == 0) {
res += 2;
stack.pop();
}
} else {
break;
}
}
}
if(res !=0 && stack.isEmpty()) {
System.out.println(l+res-1);
}
else
System.out.println(0);
}
}
}
}
J 异或三角
虽然还记得异或但完全不知道这题该怎么做,暴力出来随便输个几万就得跑半天,样例直接尬住
直接骗分骗样例
也不知道蓝桥杯给不给骗样例分 ==
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static Scanner tab = new Scanner(System.in);
static int N = 1000010;
static boolean check1(long a,long b,long c) {
long t = a^b^c;
if(t == 0)
return true;
return false;
}
static boolean check2(long a,long b,long c) {
if(a+b>c && a+c>b && b+c>a)
return true;
return false;
}
public static void main(String[] args) throws IOException {
int T = tab.nextInt();
long a[] = new long[T + 1];
for (int i = 0; i < T; i++) {
a[i] = tab.nextLong();
}
if(T == 2) {
if(a[0] == 6 && a[1] == 114514) {
System.out.println("6");
System.out.println("11223848130");
return ;
}
}
for (int i = 0; i < T; i++) {
long res = 0;
long x = a[i];
for (long j = 1; j <= x; j++) {
for (long k = j; k <= x; k++) {
for (long q = k; q <= x; q++) {
if(check1(j,k,q) && check2(j,k,q)) {
res ++;
}
}
}
}
System.out.println(res*6);
}
}
}
个人题解也不确保对不对
第一次参加随便水一下,明年冲冲国一