本篇文章中的题解是我所写的代码且都是可以运行通过的, 总结出的一篇相对来说比较清晰的个人题解, 希望要备战蓝桥杯的小伙伴能够看到最后(由于本人要参加的是Java组, 所以后面的题解基本都是使用Java写的)~
问题描述:
小蓝准备用 256MB 的内存空间开一个数组,数组的每个元素都是 32 位 二进制整数,如果不考虑程序占用的空间和维护内存需要的辅助空间,请问 256MB 的空间可以存储多少个 32 位二进制整数?
思路: 256MB = 256 * 1024 * 1024字节, 而一个字节等于8bit, 所以32位等于4字节, 最后除以四即可.
Java代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int t = 256 * 1024 * 1024;
System.out.println(t / 4);
}
}
问题描述:
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右 边的那个数。此外,向左下走的次数与向右下走的次数相差不能超过 1。
思路: 自上而下进行遍历, 查看三角形左上方和右上方那个数值更大一点, 选择更大的加下来即可, 但是由于这道题有一个限制: 向左下走的次数与向右下走的次数相差不能超过1, 所以无论怎么走, 走到最后一行的时候, 一定是在中间位置的, 根据这一特性找到最大值即可.
Java代码:
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[][] q = new int[n + 1][n + 1];
for(int i = 1; i <= n; i++){
for(int j = 1; j <= i; j++){
q[i][j] = scanner.nextInt();
}
}
for(int i = 2; i <= n; i++){
for(int j = 1; j <= i; j++){
q[i][j] += Math.max(q[i - 1][j], q[i - 1][j - 1]);
}
}
if(n % 2 == 0){
System.out.println(Math.max(q[n][n / 2], q[n][n / 2 + 1]));
}else{
System.out.println(q[n][n / 2 + 1]);
}
}
}
问题描述:
小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天 做 a 道题目, 周六和周日每天做 b 道题目。请你帮小明计算, 按照计划他将在 第几天实现做题数大于等于 n 题?
思路: 直接模拟即可, 判断需要多少个星期多几天, 注意这道题需要使用long来存储.
Java代码:
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
long a = scanner.nextLong();
long b = scanner.nextLong();
long n = scanner.nextLong();
long day = 0;
long num = 0;
long tmp = 5 * a + 2 * b;
long d = n / tmp * 7;
n %= tmp;
while(num < n){
day++;
if(day % 7 == 6 || day % 7 == 0){
num += b;
}else{
num += a;
}
}
System.out.println(day + d);
}
}
问题描述:
定义阶乘 n! = 1 × 2 × 3 × · · · × n。请问 100! (100 的阶乘)有多少个正约数。
思路: 先将1到100中所有数的所有约数存起来(这一步就相当于分解一个数的质因数), 这样我们就得到了100! 分解成1乘到100的数的所有约数, 最后我们只需要根据公式: 将每一个约数的总数量+1乘在一起就可以得到100! 的约束个数.
Java代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
int[] arr=new int[110];
for (int i=2;i<=100;i++){
int n=i;
for (int j=2;j*j<=n;j++ ){
while (n%j==0){
arr[j]++;
n/=j;
}
}
if (n>1){
arr[n]++;
}
}
long ans=1;
for (int i=2;i<=100;i++){
if (arr[i]>0){
ans*=(arr[i]+1);
}
}
System.out.println(ans);
}
}
问题描述:
蓝桥学院由 21 栋教学楼组成,教学楼编号 1 到 21。对于两栋教学楼 a 和 b,当 aa 和 b 互质时,a 和 b 之间有一条走廊直接相连,两个方向皆可通行,否则没有直接连接的走廊。
小蓝现在在第一栋教学楼,他想要访问每栋教学楼正好一次,最终回到第一栋教学楼(即走一条哈密尔顿回路),请问他有多少种不同的访问方案?
两个访问方案不同是指存在某个 i,小蓝在两个访问方法中访问完教学楼 i 后访问了不同的教学楼。
思路: 先将互为质数的教学楼两两连接起来(无向边, 两边都要连接), 接下来就是dp, 定义当前方案i的情况下以j为终点的方案数, 最后在路径求和的时候, 将以1到21为终点的教学楼都累加起来即可, 因为教学楼1与其他任意教学楼都会有边(1和任意数都是互为质数). 当然, 这样写肯定是会超时的, 但是在比赛中这是一道填空题, 所以我们只需要将计算的结果写入即可.
Java代码:
public class Main{
public static int gcd(int a, int b){
return b != 0 ? gcd(b, a % b) : a;
}
public static void main(String[] args){
boolean[][] v = new boolean[25][25];
long[][] dp = new long[1 << 21][25];
long res = 0;
for(int i = 1; i <= 21; i++){
for(int j = 1; j <= 21; j++){
if(gcd(i, j) == 1){
v[i - 1][j - 1] = true;
v[j - 1][i - 1] = true;
}
}
}
dp[1][0] = 1;
for(int i = 1; i < (1 << 21); i++){
for(int j = 0; j < 21; j++){
if(((i >> j) & 1) == 0) continue; //当前状态中不存在楼j
//寻找从楼j能够到达的下一栋楼
for(int k = 0; k < 21; k++){
if(((i >> k) & 1) == 1 || v[j][k] == false) continue;
dp[i + (1 << k)][k] += dp[i][j];
}
}
}
//将以i为结尾点的回路求和
for(int i = 0; i < 21; i++)
res += dp[(1 << 21) - 1][i];
System.out.println(res);
}
}
未完待续…