A题 (填空):
小蓝一觉醒来,发现自己被困在一座高耸的塔中。这座塔共有 2025 层,每一层都刻有一个数字的立方值,从底层的 1^3,2^3,3^3,… 一直到顶层的 2025^3,层层叠叠,直入云霄。塔顶有一扇门,门旁刻着一行字:“若想离开此塔,需找出这些立方数中个位数字为 3 的数的个数。”
小蓝非常着急,因为他需要尽快离开这座塔,去参加即将到来的蓝桥杯比赛。时间紧迫,请你帮助他解答这个问题。
解题思路:标准的签到题,需要从1^3到2025^3的立方中找出个位数字为3的数有多少个。
直接暴力找,但要注意,2025^3不是一个小数字,java要开long。
代码如下:
public class Main {
//判断个位数字,直接对10取余
public static boolean isThree(long num) {
return (num % 10)==3;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int count=0;
for(int i=1;i<=2025;i++) {
long temp = (long) Math.pow(i, 3);
if(isThree(temp)) {
count++;
}
}
System.out.println(count);
//输出202
}
}
B题(填空):
题目描述
“蓝宝又不见了!” 2025 年 4 月 12 日,蓝桥杯吉祥物 “蓝宝” 在省赛前夕突然失踪。小蓝翻阅了蓝宝的活动记录,发现它的出现时间似乎与蓝桥杯的两个重要日期密切相关:
- 第十六届省赛日期 20250412。
- 第十五届省赛日期 20240413。
经过分析,小蓝推测蓝宝的下一次出现时间 N 满足以下条件:
- N+20250412 能被 20240413 整除。
- N+20240413 能被 20250412 整除。
现在,请你帮小蓝找出满足条件的最小正整数 N,预测蓝宝的下一次出现时间。
第二题,考场坑了我不少,一眼看这个题简单,然后做了好久,终于想出来,然后理所当然的错了……还耽误了时间,所以这种比赛,如果一个题困太久了就应该放弃,5分不值得。
解题思路:
这个题从1开始全部遍历一遍肯定超时,所以需要做一些优化。
我们可以将条件进行转化,N+20250412 = i* 20240413 ==> N = (i* 20240413) - 20250412。
上面的式子表示满足第一个条件的数。
然后我们去满足第一个条件的数中去找,判断它是否满足第二个条件,如果满足,就可以找到。
代码如下:
public class problem2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int a = 20250412;
int b = 20240413;
//转化条件 N+20250412 能被 20240413 整除。N = i*20240413-20240412
//转化条件 N+20240413 能被 20250412 整除。N = i*20250412-20240413
for(long i =1;i<Long.MAX_VALUE-1;i++) {
long temp = (i*a) -b;//已经满足第一个条件,在判断第二个即可。
if((temp+20250412) % 20240413==0) {
System.out.println(temp);
//答案:409876661809331
break;
}
}
}
}
C题(编程题第一题):
题目描述
研究员小蓝受到实验室主任的指示,需要对实验室新研发的 N 个新型能量电池进行分组实验。这 N 个能量电池的能量值分别用 A1,A2,…,AN 表示,每个能量值都是一个整数。为了保证实验的安全性,小蓝需要将这 N 个能量电池分成两组,使得这两组能量电池的能量值异或和相等。
能量值的异或和计算方法如下:对于一个集合 S,其异或和等于集合中所有元素的按位异或结果。例如,集合 {1,2,3} 的异或和为 1⊕2⊕3=0,其中 ⊕ 表示异或运算。
现在,小蓝想知道,这 N 个能量电池能否分成两组,使得这两组能量电池的能量值异或和相等。注意,每组至少包含一个能量电池。
请你帮帮他!
输入格式
输入的第一行包含一个整数 T,表示测试用例的数量。
每个测试用例占两行:
- 第一行包含一个整数 N,表示能量电池的数量。
- 第二行包含 N 个整数 A1,A2,…,AN,表示每个能量电池的能量值。
输出格式
对于每个测试用例,输出一行。如果可以将能量电池分成两组,使得这两组能量电池的能量值异或和相等,则输出 YES
;否则,输出 NO
。
输入输出样例
输入
2 3 1 2 3 4 1 2 3 4
输出
YES NO
解题思路:这题考察异或和的性质,知道就好做,不知道就只能去暴力。
首先异或的性质:结合律 (A⊕B)⊕C = A⊕(B⊕C)
交换律:A⊕B = B⊕A
还有个两个比较重要的:A⊕A=0,A⊕0=A
即任何一个数异或自己的结果是0。
0异或任何数的结果都是那个数本身。
知道这些性质后,才可以从题目条件反推。题目要分成两个异或和相等的组,第一个组的总和SumA = a1⊕a2……⊕ai ,第二个组SumB =aj⊕aj+1……an;有题目条件可得 SumA ==SumB,再根据异或的性质,即SumA⊕SumB==0;又根据结合律,你先算SumA和SumB异或和再计算它们两的异或和,与直接算所有元素的异或和结果是一样的,所以可以化简成直接计算所有元素的异或和,如果等于0,说明可以分成两组相等的电池,否则就不行。
代码如下:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while(n>0) {
int length = sc.nextInt();
int arr [] =new int[length];
int result=0;
for(int i =0;i<arr.length;i++) {
arr[i]=sc.nextInt();
result ^= arr[i];
}
if(result==0) {
System.out.println("YES");
}else {
System.out.println("NO");
}
n--;}
}
}
D题(编程题第二题):
题目描述
小明正在参加魔法科的期末考试,考生需要根据给定的口诀组合出有效的魔法。其中,老师给定了 n 个上半部分口诀 a1,a2,…,an 和 m 个下半部分口诀 b1,b2,…,bm,均用整数表示。完整的口诀包含一个上半部分口诀和一个下半部分口诀,当选用两个口诀 ai 和 bj,将组合出完整口诀 S=ai+bj。
当 S 满足 S≤n+m 且 S 为质数时,魔法是有效的。魔法的种类只和 S 的大小有关。如果每个上半部分口诀和每个下半部分口诀在不同的组合中可以重复使用,小明想知道一共可能组合出多少种不同的有效魔法?
输入格式
输入共三行。
- 第一行为两个正整数 n,m。
- 第二行为 n 个由空格分开的正整数 a1,a2,…,an。
- 第三行为 m 个由空格分开的正整数 b1,b2,…,bm。
输出格式
输出共 1 行,一个整数表示答案。
输入输出样例
输入
3 4 2 3 10 3 4 5 1
输出
3
可以组合出 3,5,7 这三个有效魔法。
评测用例规模与约定
-
对于 20% 的评测用例,n,m≤200。
-
对于 60% 的评测用例,n,m≤2000。
-
对于 100% 的评测用例,1≤n,m≤20000,1≤ai,bi≤20000。
解题思路:题意应该算是比较简单的,从给出的两组数组中各选出一个数a和b,组成魔法口诀S,当S<=n+m且为质数时为有效。需要注意的是,有效的个数只跟组合成的质数有关(重复的S不算,但是元素之间是可以随便组的),也就是需要对结果S进行去重。
如果每次得到的S都对这个数去扫一遍他的因数从未判断是否为质数,做了许多重复工作,会超时。这个太过于暴力了,不过也可以得到40%的分数,下面的代码也给出了这个方法。
这时候就需要对数据进行预处理,也就是提前得一定范围的质数表,只要根据这个质数表判断就行,这个过程只需要做一次。
这个方法叫做埃氏筛,从1到给定的范围,从最小的质数开始,依次划掉这个质数的倍数(划掉的这个数一定不是质数,因为之前的质数是他的倍数),然后依次递推,就能得到一份质数表。
代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
public class Main{
//埃氏筛
public static boolean[] iszhi(int limit) {
boolean is [] =new boolean[limit+1];
for(int i=0;i<=limit;i++) {
is[i]=true;
}
is[1]=false;
for(int i=2;i*i<=limit;i++) {
if(is[i]) {
for(int j=i*i;j<=limit;j+=i) {
is[j]=false;
}
}
}
return is;
}
//一般判断质数
public static boolean iszhi2(int num) {
if(num <=1) return false;
boolean is = true;
for(int i=2;i <= Math.sqrt(num);i++ ) {
if((num % i) ==0) {
is = false;
}
}
return is;
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str1 []= br.readLine().split(" ");
int n = Integer.parseInt(str1[0]);
int m = Integer.parseInt(str1[1]);
int arr [] =new int[n];
int brr [] =new int[m];
String str2 []= br.readLine().split(" ");
String str3 []= br.readLine().split(" ");
for(int i=0;i<n;i++) {
arr[i] = Integer.parseInt(str2[i]);
}
for(int i=0;i<m;i++) {
brr[i] = Integer.parseInt(str3[i]);
}
Map<Integer,Boolean> map =new HashMap<>();
int S =n+m;
boolean [] isS = iszhi(S);
int ans=0;
for(int i=0;i<arr.length;i++) {
for(int j=0;j<brr.length;j++) {
if(arr[i]+brr[j]<= S && isS[arr[i]+brr[j]] && !map.containsKey(arr[i]+brr[j])) {
ans++;
map.put(arr[i]+brr[j], null);
}
}
}
System.out.println(ans);
}
}
以上代码均经过校验,如有问题,欢迎私信联系更改和指出。
总结:最终获得省一。比赛最重要的是自己的收获,算法比较考验临场发挥的能力,运气,实力缺一不可。
还有下半部分……未完待续……