目录
前言
总的来说,北京、天津和河北蓝桥杯今年的考题相比较前几年还是比较简单的,很多题暴力就能解。因为考试期间北京、天津和河北一些地方刮大风,考试时间延后了,用了备用卷,而且我目前知道python B组跟Java B组的题一样的。去年蓝桥杯捐款了,罚坐了四个小时。今年刷了很多简单题,备考了几个月。考试时间也不够了,最后一道题没写。好了废话不多说,直接看题吧~
(个人解题答案,仅供参考)
试题A:密密摆放(5分)
【问题描述】 小蓝有一个大箱子,内部的长宽高分别是 200 、250 、240 (单位:毫米), 他要用这个大箱子来放一些同样大小的小盒子,小盒子的外部长宽高分别是 30、40、50 (单位:毫米)。小盒子允许从各个方向旋转(包括可以平放和倒 放)。 请问小蓝最多可以在一个大箱子里面放多少个小盒子。
【答案提交】这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个 整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
思路:
没参加过蓝桥杯算法比赛的同学要注意,考试时候前两道是填空题,只填数字,不用写代码。
这道题乍一看挺难没有思路,但仔细观察大箱子小箱子的尺寸数据就能找到规律。小箱子宽长高:40 50 30,大箱子宽长高:200 250 240。大箱子长宽是分别是小箱子的5倍,高是小箱子的8倍,小箱子放 5✖5✖8 = 200个刚好能把大箱子放满。
最后用体积验证一下:200*30*40*50 = 200*250*240 √
答案: 200
试题 B: 脉冲强度之和(5分)
【问题描述】 在蓝桥电子工坊,工程师小蓝正在设计一款智能脉冲生成器,用于驱动一 种新型设备。该设备的运行依赖于特定的脉冲强度,用正整数 p 表示,其必须 满足以下三个条件:
1. 可由连续 10 个正整数之和组成:即存在一个正整数 k ,使得脉冲强度 p = k + (k + 1) + (k + 2) + · · · + (k + 9) 。
2. 各个数位上的数字都相同:例如 1111 、22222 、333333 等。
3. 数值不超过 20255202:即 1 ≤ p ≤ 20255202。通过计算所有符合条件的脉冲强度之和,小蓝能够优化设备运行模式。对此,请帮助他计算这一总和。
【答案提交】 这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个 整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
思路:
脉冲强度p是一个等差数列(虽然考试时候等差公式忘了),
等式推导一下:p = 10k + 45,其中k为正整数,所以p可以从55开始找。(从推导的等式能看出最后p的个位是5,再加上条件2,满足条件的只能在55,555,5555···中查找)
条件1:遍历所有p(1 ≤ p ≤ 20255202)判断(p - 45)是否能被10整除
条件2:可以用 x模以10再除以10取出x的每一位 再定义一个变量记录上一个数位的值,判断是否相等
答案: 6172830
注意考试中Java 定义类名只能是Main
public class Main {
public static void main(String[] args) {
Long ans = 0L;
for(int i = 45;i<20255202;i++) {
if(check(i) && (i-45)%10==0) {
ans+=i;
}
}
System.out.print(ans);
}
public static boolean check(int i) { //判断每一个数位是否相同
int last =i%10; //定义last记录个位数值
i/=10;
while(i>0) { //取每一个数位
if(i%10!=last) return false;
i/=10;
}
return true;
}
}
试题 C: 25 之和(10分)
【问题描述】 小蓝最近对求和很着迷,给定一个正整数 n ,他想求从 n 开始的连续 25 个整数的和,即 n + (n + 1) + (n + 2) + · · · + (n + 24) ,请帮帮他吧。
【输入格式】 输入一行包含一个正整数 n 。
【输出格式】 输出一行包含一个整数表示答案。
【样例输入 1】 1
【样例输出 1】 325
【样例输入 2】 100
【样例输出 2】 2800
【评测用例规模与约定】
对于 40% 的评测用例,1 ≤ n ≤ 100 ;
对于所有评测用例,1 ≤ n ≤ 10000 。
思路:
不知道这次出题人为什么那么钟爱等差数列,一个循环就能解决,n最大10000也不会超范围
答案:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); //怕超范围用了Long类型
Long ans = 0L;
for(int i = n;i<n+25;i++) {
ans+=i;
}
System.out.print(ans);
}
}
试题D:旗帜(10分)
【问题描述】 小蓝要画一个 LANQIAO 图形,并把这个图形做成一个旗帜。图形的形状 为一个 h×w 的矩形,其中 h 表示图形的高,w 表示图形的宽。
当 h = 5,w = 10 时,图形如下所示:
L A N Q I A O L A N
A N Q I A O L A N Q
N Q I A O L A N Q I
Q I A O L A N Q I A
I A O L A N Q I A O
图形的规律是:第一行用 LANQIAO 重复填入,第二行开始,每行向左移 动一个字符,用 LANQIAO 重复填入。 小蓝需要把图形中的每个字母都剪出来,以粘贴到旗帜上,他想知道,给 定图形的高和宽,图形中有多少个 A 。
【输入格式】 输入的第一行包含两个正整数 h,w ,用一个空格分隔。
【输出格式】 输出一行包含一个整数表示答案。
【样例输入】 5 10
【样例输出】 14
【评测用例规模与约定】 对于 30% 的评测用例,h = 1 ,1 ≤ w ≤ 20 ; 对于 60% 的评测用例,1 ≤ h,w ≤ 20 ; 对于所有评测用例,1 ≤ h,w ≤ 100 。
思路:
这道题可以先尝试输出矩阵,再统计 'A' 的数。输入矩阵,输出矩阵都可以用两层for循环嵌套,包括三角矩阵。再就是字符 LANQIAO 的循环,可以定义一个字符数组,通过定义一个变量每次自增再模以7(0~6)作数组索引 实现字符 LANQIAO 的循环。
h,w最大100,不用再考虑时间复杂度的问题
答案:
import java.util.Scanner;
public class Main {
static char[] arr = {'L','A','N','Q','I','A','O'};
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int h = sc.nextInt();
int w = sc.nextInt();
int ans = 0; //记录答案
for(int i=0 ;i<h;i++) { //控住行号
for(int j=i ;j<w+i;j++) { //控住每一行
//System.out.print(arr[j%7]); 输出矩阵
if(arr[j%7] == 'A') ans++;
}
//System.out.println(); 换行,用于输出矩阵
}
System.out.print(ans);
}
}
试题 E: 数列差分(15分)
【【问题描述】 小蓝有两个长度均为 n 的数列 A = {a1, a2, · · · , an} 和 B = {b1, b2, · · · , bn} , 将两个数列作差定义为 C = A − B = {c1 = a1 − b1, c2 = a2 − b2, · · · , cn = an − bn}。小蓝将对数列 B 进行若干次操作,每次操作可以将数列 B 中的任意一个数更改 为任意一个整数。在进行完所有操作后,小蓝可以按任意顺序将数列 B 重排,之后再计算数列 C 。小蓝想知道最少操作多少次可以使得数列 C 中的所有数 都为正整数。
【输入格式】 输入的第一行包含一个正整数 n ;第二行包含 n 个整数 a1, a2, · · · , an ,相邻整数之间使用一个空格分隔 第三行包含 n 个整数 b1, b2, · · · , bn ,相邻整数之间使用一个空格分隔。
【输出格式】 输出一行包含一个整数表示答案。
【样例输入】 4 22 31 12 14 3 19 27 44
【样例输出】 1
【样例说明】 其中一种方案:将 44 改为 0 ,重新排列 B 为 {19, 27, 3, 0} ,使得数列 C = {3, 4, 9, 14} 均为正整数。
【评测用例规模与约定】 对于 30% 的评测用例,n ≤ 10 ; 对于所有评测用例,1 ≤ n ≤ 105 ,−10^9 ≤ ai ≤ 10^9 ,−10^9 ≤ bi ≤ 10^9 。
思路:
这道题有贪心算法的思维,数列的贪心求最优解一般都会用到排序,这道题给序列排完序再用上队列就会很简单。
先将数组正常从小到大排完序,再分别存入队列A,队列B(数值小存在队头),如果队列A队头大于队列B队头,队列A和队列B正常弹出;否则,队列A正常弹出,队列B不弹出(相当于队列B往后挪一位,如果队列B队头还大接着往后挪)直到找到队列B中最小值的最优解。结束条件是当队列A位空,队列B剩余数据的长度就是答案。
答案:
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Queue<Integer> qA = new LinkedList<>();
Queue<Integer> qB = new LinkedList<>();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arrA = new int[n];
int[] arrB = new int[n];
for (int i = 0; i < n; i++) arrA[i] = sc.nextInt();
for (int i = 0; i < n; i++) arrB[i] = sc.nextInt();
Arrays.sort(arrA); //排序
Arrays.sort(arrB);
for (int i = 0; i < n; i++) qA.add(arrA[i]); //存入队列
for (int i = 0; i < n; i++) qB.add(arrB[i]);
qA.remove();
while (!qA.isEmpty() && !qB.isEmpty()) {
int xA = qA.element();
int xB = qB.element();
if(xA >= xB){ //正常弹出
qA.remove();
qB.remove();
}else qA.remove(); //找队列B当前队头的最优解
}
System.out.println(qB.size());
}
}
试题 F: 基因配对(15分)
【问题描述】 小蓝发现了一种奇特的生物,它的遗传信息可以表示为一个长度为 n 的 01 串 s = s0 s1 · · · sn−1 ,其中的任意一段子串 sl,r = sl s(l+1) · · · sr 则可以构成一个基 因。 我们称遗传信息的某两个位置相反,是指这两个位置上的字符不相同(即 其中一个为 0 ,另一个为 1 )。 小蓝想知道,有多少对不相交的相同长度的基因正好相反,即有多少对 [(a, b),(c, d)] 满足 0 ≤ a ≤ b < c ≤ d < n 且子串 sa,b 和子串 sc,d 的每个位置恰好 相反。
【输入格式】 输入一行包含一个长度为 n 的 01 串 s 。
【输出格式】 输出一行包含一个整数表示答案。
【样例输入】 10011
【样例输出】 8
【样例说明】 有以下 8 对子串满足条件:[(0, 0),(1, 1)]、[(0, 0),(2, 2)]、[(1, 1),(3, 3)]、[(1, 1),(4, 4)] 、[(2, 2),(3, 3)] 、[(2, 2),(4, 4)] 、[(0, 1),(2, 3)] 、[(1, 2),(3, 4)] 。
【评测用例规模与约定】 对于30%的评测用例,1 ≤ n ≤ 20 ;对于所有评测用例,1 ≤ n ≤ 1000 。
思路:
这道题的for循环还是有点麻烦的,容易超时,容易把人绕晕。注意题意 :“有多少对不相交的相同长度的基因正好相反”,我刚开始做这道题还在想吧01串转成对应的十进制数字来优化判断,但实在是太麻烦了十进制数字“1”的01串有“1”, “01”, “001”, “0001”···.。
这道题直接用暴力解,先固定需要找子串Sa,b,再在Sa,b位置往后找与当前串相同长度的子串,最后匹配是否满足条件。注意理解循环体代表的含义,找子串的循环很绕,而且超时了,直接看代码吧。
我的答案n>200就已经超时了,可以试着预处理字符差异,用二维数组预存子串差异标记,把 check 操作优化为 O(1)。
答案:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next();
int len = s.length();
int ans = 0;
//不相交,长度到主串的一半就可以结束循环
for (int i = 1; i <= len/2; i++) { //i代表 Sa,b 串长度
for (int k = 0; k+i < len; k++) { //k代表 Sa,b 串的起始位置
String si = s.substring(k, k+i); // 取出 Sa,b
//不相交 获取位置k后面长度为i的字串Sc,d
for (int j = k+1; j+i <= len; j++) { //j代表 Sa,b 串的起始位置,长度为i
String se = s.substring(j, j + i); 取出 Sc,d
if (check(si, se)) ans++; //判断
}
}
}
System.out.println(ans);
}
public static boolean check(String s1, String s2){
int len = s1.length();
for (int i = 0; i < len; i++) {
if (s1.charAt(i) == s2.charAt(i)) return false;
}
return true;
}
}
试题 G: 栈与乘积(20分)
【问题描述】 给定一个栈,给出若干次如下类型的操作:
1 x: 将 x 加入栈顶。
2: 将栈顶的数弹出(如果栈是空的,则什么都不做)。
3 y: 查询栈内的最顶端 y 个数的乘积。如果大于等于 2 32 ,输出OVERFLOW。 如果栈内不足 个数,输出 ERROR 。
【输入格式】 输入的第一行包含一个正整数 Q ,表示操作次数。 接下来 Q 行,每行包含一个或两个正整数表示一个操作,如果一行包含两 个整数,两个整数之间用一个空格分隔。
【输出格式】 对于每个 3 y 形式的操作,输出一行包含一个整数,表示答案。
【样例输入】 9 1 65536 1 65536 3 2 3 3 2 1 1024 1 2 3 2 3 3
【样例输出】 OVERFLOW ERROR 2048 134217728
【评测用例规模与约定】 对于 30% 的评测用例,Q ≤ 5000 ; 对于所有评测用例,1 ≤ Q ≤ 10^5 ,0 ≤ x < 2^30 ,1 ≤ y < 2^30 。
思路:
感觉这个题不难,也不知道是不是自己想简单了。测试数据范围比较大,我用的Java BigInteger类应该不会有问题吧
主要是栈的操作,我用ArrayList 模拟栈的操作,加入了一个队头指针。
答案:
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
BigInteger cnt = new BigInteger("4294967296");
Scanner sc = new Scanner(System.in);
ArrayList<BigInteger> list = new ArrayList<>();
int h = 0; //头指针
int n = sc.nextInt();
while (n-- > 0) { //n次操作
int i = sc.nextInt();
if (i == 1){
String s = sc.next();
if (list.size() > h){
list.set(h, new BigInteger(s));
}else{
list.add(new BigInteger(s));
}
h++;
} else if (i == 2) {
if (!list.isEmpty()) h--;
}else{
int x = sc.nextInt();
if(x > h) System.out.println("ERROR"); //超过x个元素
else {
BigInteger s = BigInteger.valueOf(1); //乘积
int index = h-1;
while (x-- > 0) {
BigInteger y = list.get(index);
s = s.multiply(y);
index--;
}
if (cnt.compareTo(s) > 0) System.out.println(s);
else System.out.println("OVERFLOW");
}
}
}
}
}
试题 H: 破解信息(20分)
【问题描述】 在遥远的未来,星际旅行已经成为常态。宇航员小蓝在一次探险任务中, 意外发现了一个古老的太空遗迹。遗迹中存放着一个数据存储器,里面记录着 一段加密的信息。经过初步分析,小蓝发现这段信息可以被表示为一个字符串 S,而解密的关键,在于找出 S 中字典序最大的回文子序列。 子序列:指从原字符串中抽取若干个字符(可以不连续),按照它们在原 字符串中的相对顺序排列所形成的新序列。例如,对于字符串 “abc”,其 子序列包括 “a”、“b”、“c”、“ab”、“ac”、“bc” 和 “abc”。 • 字典序:指字符串按照字典中的排序规则比较大小的方式。对于两个字符 串,从左到右逐字符比较,先出现较大字符的字符串字典序更大;若比较 到某个字符串结束仍未找到不同的字符,则较短的字符串字典序较小。例 如,“abc” < “abd”,而 “ab” < “abc”。 现在,请你从字符串 S 中,找出字典序最大的回文子序列,帮助小蓝解开 这段来自星际文明的信息。
【输入格式】 输入一行包含一个字符串 S ,表示加密的信息。
【输出格式】 输出一行包含一个字符串,表示 S 中字典序最大的回文子序列。
【样例输入 1】 abcd
【样例输出 1】 d
【样例输入 2】 abab
【样例输出 2】 bb
【评测用例规模与约定】 对于 30% 的评测用例,1 ≤ |S | ≤ 300 ,其中 |S | 表示字符串 S 的长度; 对于所有评测用例,1 ≤ |S | ≤ 105 ,S 中只包含小写英文字母。
思路:无
答案: 无
以上仅是个人答案,仅供参考,欢迎讨论
球球给我个省一吧,备考了那么久,真的球球了。
学的递归,深搜广搜全都没考。呜呜呜,老实了求放过。