2021十二届蓝桥杯Java B国赛(原题+部分题解)

前前后后准备了快两个月,还算有所收获,国奖应该能拿个,不过感觉国赛的题比省赛简单的多就很迷

A 整数范围

在这里插入图片描述
签到,刚开始还以为有什么坑斟酌了半天

	public static void main(String[] args) {
		String s ="11111111";
		int x = Integer.parseInt(s,2);
		System.out.println(x);
	}

255


B 纯质数在这里插入图片描述

常规题,欧拉筛出质数再遍历一遍判断即可,反正是填空怎么筛都行

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);
			
			
		}
	}
}


个人题解也不确保对不对
第一次参加随便水一下,明年冲冲国一

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值