Java && C++ 实现第十二届蓝桥杯 C++ B组 D货物摆放 E路径

128 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

虽然是C++组的,但是和Java组的差不了两道题,大家都可以看一看 如有错误,还请佬 评论或私信指出(写的稍些急) 再也不肝博客了 /(ㄒoㄒ)/~~

(由于上传图片有限制,如果描述不清楚点击手写题解) 手写题解字丑,但是小编感觉会比文字看的直观一些(其实是不会用数学公式)

编程题测试数据

C++B组手写题解(如果访问出错,请刷新访问的页面即可(Nebo的问题))

当前页面的编程题均在C语言网成功运行 C语言网有各届蓝桥杯的题库 第十二届蓝桥杯编程题测试 刷题集

在这里插入图片描述

试题 D: 货物摆放

本题总分:10 分

【问题描述】

小蓝有一个超大的仓库,可以摆放很多货物。

现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝

规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、

宽、高。

小蓝希望所有的货物最终摆成一个大的立方体。即在长、宽、高的方向上

分别堆 L、W、H 的货物,满足 n = L × W × H。

给定 n,请问有多少种堆放货物的方案满足要求。

例如,当 n = 4 时,有以下 6 种方案:1×1×4、1×2×2、1×4×1、2×1×2、

2 × 2 × 1、4 × 1 × 1。

请问,当 n = 2021041820210418 (注意有 16 位数字)时,总共有多少种

方案?

提示:建议使用计算机编程解决问题。

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一

个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

package LanqiaobeiExam._12CB;

/**
 * ClassName: D货物摆放
 * Package: LanqiaobeiExam._12CB
 *
 * @DATE: 2022/3/21 17:00
 * Author: asleep
 */
public class D货物摆放 {    //2430
    public static void main(String[] args) {    //直接遍历 n 会炸,我们这里遍历 n 的约数,相对复杂度会低很多
        long n = 2021041820210418L;
        long[] res = new long[10000];
        int index = 0;
        for (long i = 1L; i <= n / i; i++) {
            if (n % i == 0) {
                res[index++] = i;
                if (i * i != n) {
                    res[index++] = n / i;
                }
            }
        }
        int count = 0;
        for (int i = 0; i < index; i++) {
            for (int j = 0; j < index; j++) {
                if (n % (res[i] * res[j]) == 0) {
                    count++;
                }
            }
        }
        System.out.println(count);
    }
}

试题 E: 路径

本题总分:15 分

【问题描述】

小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图

中的最短路径。

小蓝的图由 2021 个结点组成,依次编号 1 至 2021。

对于两个不同的结点 a, b,如果 a 和 b 的差的绝对值大于 21,则两个结点

之间没有边相连;如果 a 和 b 的差的绝对值小于等于 21,则两个点之间有一条

长度为 a 和 b 的最小公倍数的无向边相连。

例如:结点 1 和结点 23 之间没有边相连;结点 3 和结点 24 之间有一条无

向边,长度为 24;结点 15 和结点 25 之间有一条无向边,长度为 75。

请计算,结点 1 和结点 2021 之间的最短路径长度是多少。

提示:建议使用计算机编程解决问题。

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一

个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

Dijkstra最短路径

Java与C++解法相同

package LanqiaobeiExam._12CB;

import java.util.Arrays;

/**
 * ClassName: E路径
 * Package: LanqiaobeiExam._12CB
 *
 * @DATE: 2022/3/21 17:08
 * Author: asleep
 */
public class E路径 {  //10266837
    static int[][] map = new int[2022][2022];
    public static int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }
    public static int dijkstra() {    //通过Dijkstra算法求出已知路径距离获取最短路径
        int[] distance = new int[2022];    //声明最短距离的路径
        Arrays.fill(distance, 0xffffff);
        boolean[] visited = new boolean[2022];
        distance[1] = 0;    //起始点为1
        for (int i = 1; i < 2022; i++) {
            int temp = -1;
            for (int j = 1; j < 2022; j++) {  //只要找到其他的点,或者小于已搜索的距离,就指定下一个目标
                if (!visited[j] && (temp == -1 || distance[j] < distance[temp])) {
                    temp = j;
                }
            }
            visited[temp] = true;    //当前目标被访问了,
            for (int j = 1; j < 2022; j++) {    //更新通过目标结点到其他结点的最短距离
                distance[j] = Math.min(distance[j], distance[temp] + map[temp][j]);
            }
        }
        return distance[2021];
    }


    public static void main(String[] args) {  //初始化默认的距离
        for (int i = 1; i < 2022; i++) {
           for (int j = 1; j < 2022; j++) {
               if (i != j) {
                   if (Math.abs(i - j) <= 21) {
                       map[i][j] = i * j / gcd(i, j);
                       map[j][i] = map[i][j];
                   } else {
                       map[i][j] = 0xffffff;
                       map[j][i] = map[i][j];
                   }
               }
           }
        }
        System.out.println(dijkstra());



    }
}

#include <cstring>
#include "cmath"
#include "iostream"

using namespace std;

const int N = 2030;
int n = 2021;
int dis[N], map[N][N], visited[N];


int Dijkstra() {    //10266837
    memset(dis, 0x3f3f3f3f, sizeof(dis));
    dis[1] = 0;
    for (int i = 1; i <= n; i++) {
        int temp = -1;
        for (int j = 1; j <= n; j++) {
            if (!visited[j] && (temp == -1 || dis[j] < dis[temp])) {
                temp = j;
            }
        }
        visited[temp] = 1;
        for (int j = 1; j <= n; j++) {
            dis[j] = min(dis[j], dis[temp] + map[temp][j]);
        }
    }
    return dis[n];

}

int gcd(int a,int b) {
    return b ? gcd(b, a % b) : a;
}

int main() {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (fabs(i - j) <= 21) {
                map[i][j] = i * j / gcd(i, j);
            } else {
                map[i][j] = 0xffffff;
            }
        }
    }
    cout << Dijkstra();
    return 0;
}