第十二届蓝桥杯非官方题解

A、空间

在这里插入图片描述

这个就是计算256 * 2^10 * 2^10 / 4
答案:67108864

B、卡片

在这里插入图片描述

这道题当时还考虑了一下,能不能拼出这个数字,就像题中给出情况一样,这个用代码输出的ans=11,num=-1,但是答案是10,所以也应该输出num一下看看能不能组成这个数字

#include <iostream>
using namespace std;

int main()
{
    int num = 2021, ans;
    for(int i = 1; i < 1000000 && num > 0; i ++){
        int t = i;
        ans = i;//在这里用ans来标记一下到哪个数字,如果直接用i - 1也行,不过可能考试紧张就忘了减
        while(t){
            if(t % 10 == 1) num--;
            t /= 10;
        }
    }
    cout << ans <<endl;
    return 0;
}

答案:3181

C、直线

无
对stl还不是很熟悉,先研究研究再回来写这题吧

D、货物摆放

在这里插入图片描述

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;

int main()
{
    LL n = 2021041820210418;
    LL n;
    //cin >> n;
    LL res = 0;
    for(LL i = 1; i * i * i <= n; i ++){
        if(n % i == 0){
            for(LL j = i; i * j * j <= n; j ++){//保证三个数排好序,证明自己推一下就好i*j * k = n >= i * j * j =>( k >= j)
                if(n / i % j == 0){
                    LL k = n / i / j;
                    if(i == j && j == k) res ++;//能组成多少种
                    else if(i != j && j != k) res += 6;
                    else res += 3;
                }
            }
        }
    }
    cout << res ;
    return 0;
}

答案:2430

E、路径

在这里插入图片描述

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 2200, M = N * 50;

int n;
int h[N], e[M], w[M], ne[M], idx;
int q[N], dist[N];
bool st[N];

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

void add(int a, int b, int c)  // 添加一条边a->b,边权为c
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}

void spfa()  // 求1号点到n号点的最短路距离
{
    int hh = 0, tt = 0;
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    q[tt ++ ] = 1;
    st[1] = true;

    while (hh != tt)
    {
        int t = q[hh ++ ];
        if (hh == N) hh = 0;
        st[t] = false;

        for (int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (dist[j] > dist[t] + w[i])
            {
                dist[j] = dist[t] + w[i];
                if (!st[j])     // 如果队列中已存在j,则不需要将j重复插入
                {
                    q[tt ++ ] = j;
                    if (tt == N) tt = 0;
                    st[j] = true;
                }
            }
        }
    }
}


int main()
{
    n = 2021;
    memset(h, -1, sizeof h);
    for (int i = 1; i <= n; i ++ )
        for (int j = max(1, i - 21); j <= min(n, i + 21); j ++ )
        {
            int d = gcd(i, j);
            add(i, j, i * j / d);
        }

    spfa();
    printf("%d\n", dist[n]);
    return 0;
}

F、时间显示

在这里插入图片描述
这道题好像没有啥可说的,就是得知道1秒等于几毫秒

#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
    long long n;
    cin >> n;
    n = n / 1000;
    n = n % 86400;
    int hh = n / 3600;
    int mm = n % 3600 /60;
    int w = n % 3600 % 60 ;
    printf("%02d:%02d:%02d", hh, mm,w);//这个输出格式挺好
    return 0;
}

G、砝码称重

在这里插入图片描述
这个题看y总用的动态规划做的

#include <iostream>

using namespace std;
int n, sum;
const int N = 100010;
int w[105], f[105][200020];
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i ++){
        scanf("%d", &w[i]);
        sum += w[i];//总重量
    }
    f[0][N]= 1;//都统一加了一个偏移量N
    for(int i = 1; i <= n; i ++){//
        for(int j = -sum; j <= sum; j ++){
            f[i][j + N] = f[i - 1][j + N];//如果没有加砝码
            if(j - w[i]>= -sum) f[i][j + N] |= f[i - 1][j - w[i] + N];
            if(j + w[i]<= sum) f[i][j + N] |= f[i - 1][j + w[i] + N];
        }
    }
    int ans = 0;
    for(int i = 1; i <= sum; i ++){
        if(f[n][i +N]) ans ++;
    }
    cout << ans << endl;
    return 0;
}

H、杨辉三角形

在这里插入图片描述
这道题着实没有想到(直接暴力写的),我觉得应该加强一些数学知识的能力

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
int n;
LL c(int a, int b)//排列组合函数
{
    LL ans = 1;
    for(int i = a, j = 1;j <=b; i --, j ++){
        ans = ans * i / j;
    }
    return ans;
}
bool check(int k)//判断这一斜行里是不是有n
{
    LL l = 2 * k, r = max(l, LL(n));//组合的下标,即组合函数中的a
    while(l < r){//二分查找n所在位置
        LL mid = l + r >> 1;
        if(c(mid, k) >= n) r = mid;
        else l = mid + 1;
    }
    if(c(r, k) != n) return false;//没找到就返回false
    cout << k + 1 + r * (1 + r) / 2;//所在位置,这个数所在行的前边所有数+列数(k + 1)
    return true;

}
int main()
{
    cin >> n;
    for(int k = 16; ; k --){//最大的就是16斜行
        if(check(k)) break;
    }
    return 0;
}

写一下总结吧:整个蓝桥杯题解均参考y总讲解及代码,感觉自己太菜了,天呐,算法还没怎么学,这好像是个非常严重的事情,最近先抓紧补一下算法知识吧

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值