第16届国赛蓝桥杯大赛C/C++大学C组

目录

一.最大周长

1.题目讲解

2.代码实现

二.拔河

1.题目讲解

2.代码实现

三.铺设能源管道

1.题目讲解

2.代码实现

四.打破规则

1.题目讲解

2.代码实现

五.数字配对

1.题目讲解

2.代码实现

六.宗门大比

1.题目讲解

2.代码实现

七.数列染色

1.题目讲解

2.代码实现

八.正方形构造

1.题目讲解

2.代码实现

九.杨辉三角

1.题目讲解

2.代码实现

十.整齐的数

1.题目讲解

2.代码实现


一.最大周长

题目链接:https://www.lanqiao.cn/problems/21224/learning/

1.题目讲解

或者我们可以直接使用结论(长度变长,宽度小 => 周长最长)

2.代码实现

cpp 复制代码
#include <iostream>

using namespace std;

int main()
{
    int ret = 0;
    for(int i = 1;i <= 2025;i++)
    {
        if(2025 % i == 0)
        {
            ret = max(ret,(i + 2025 / i) * 2);
        }
    }
    cout << ret << endl;
    return 0;
}

二.拔河

题目链接:https://www.lanqiao.cn/problems/21223/learning/

1.题目讲解

2.代码实现

cpp 复制代码
#include <iostream>
#include <algorithm>

using namespace std;

#define int long long
const int N = 1 << 21;

int a[] = {0, 345590635693812, 411735179294186, 190029355501347, 973598561303630,
          18202819016954, 739089526396984, 41064501651340, 287075700776565,
          458062562307032, 723278851371706, 997720296178889, 470475557480472,
          329586527903215, 907379737442406, 631284976214798, 301204036247736,
          747294692547790, 914091289062262, 144070679727924, 988094642462741,
          413975599277375, 835461430976017, 344371572186185, 646160866308904,
          880407857470630, 794629069521762, 462180977651587, 342038139286302,
          854772507978666, 694223418935656, 567502001946067, 881035713848915,
          840605474892139, 324727089144326, 226008847101330, 65143946718125,
          499249957077991, 245803813100131, 447887480320685, 658036302578844
        };

int x[N],c1,y[N],c2;

void ldfs(int pos,int sum)
{
    if(pos > 20)
    {
        x[++c1] = sum;
        return;
    }
    ldfs(pos + 1,sum + a[pos]);
    ldfs(pos + 1,sum - a[pos]);
}

void rdfs(int pos,int sum)
{
    if(pos > 40)
    {
        y[++c2] = sum;
        return;
    }
    rdfs(pos + 1,sum + a[pos]);
    rdfs(pos + 1,sum - a[pos]);
}

signed main()
{
    ldfs(1,0);
    rdfs(21,0);
    sort(x + 1,x + c1 + 1);
    sort(y + 1,y + c2 + 1);

    int ret = 1e18;
    for(int i = 1,j = c2;i <= c1;i++)
    {
        while(j >= 2 && x[i] + y[j - 1] >= 0)
        {
            j--;
        }
        ret = min(ret,abs(x[i] + y[j]));
        if(j >= 2)
        {
            ret = min(ret,abs(x[i] + y[j - 1]));
        }
    }
    cout << ret << endl;
    return 0;
}

三.铺设能源管道

题目链接:https://www.lanqiao.cn/problems/21267/learning/

1.题目讲解

我们能看到 1 / 10 / 100 / 1000 / 10000等数的花费是最小的

2.代码实现

cpp 复制代码
#include <iostream>

using namespace std;

int main()
{
    int n;
    cin >> n;
    int ret = 1;
    while(ret < n)
    {
        ret *= 10;
    }
    cout << ret << endl;
    return 0;
}

四.打破规则

题目链接:https://www.lanqiao.cn/problems/21268/learning/

1.题目讲解

2.代码实现

cpp 复制代码
#include <iostream>

using namespace std;

int main()
{
    int a,b,c;
    cin >> a >> b >> c;
    if(a == b || a == c || c == b || (a > b && b > c) || (a < b && b < c))
    {
        cout << 0 << endl;
    }
    else
    {
        cout << min(min(abs(a - b),abs(a - c)),abs(b - c)) << endl;
    }
    return 0;
}

五.数字配对

题目链接:https://www.lanqiao.cn/problems/21211/learning/

1.题目讲解

2.代码实现

cpp 复制代码
#include <iostream>
#include <vector>

using namespace std;

const int N = 1e6 + 10;

int n,m;
vector<int> p[N];

int main()
{
    cin >> n;
    for(int i = 1;i <= n;i++)
    {
        int x;
        cin >> x;
        p[x].push_back(i);
        m = max(m,x);
    }
    int cnt = 0;
    for(int x = 1;x < m;x++)
    {
        if(p[x].empty() || p[x + 1].empty())
        {
            continue;
        }
        int i = p[x].size() - 1,j = p[x + 1].size() - 1;
        while(i >= 0 && j >= 0)
        {
            if(p[x][i] < p[x + 1][j])
            {
                cnt++;
                i--;
                j--;
                p[x + 1].pop_back();
            }
            else
            {
                i--;
            }
        }
    }
    cout << cnt << endl;
    return 0;
}

六.宗门大比

题目链接:https://www.lanqiao.cn/problems/21221/learning/

1.题目讲解

然后将其差值进行排序即可

2.代码实现

cpp 复制代码
#include <iostream>
#include <algprithm>

using namespace std;

const int N = 5e5 + 10;
int n,m,k,a[N],mx;
int d[N],tot,num;

int main()
{
    cin >> n >> m >> k;
    for(int i = 1;i <= n;i++)
    {
        cin >> a[i];
        mx = max(mx,a[i]);
    }
    if(a[k] == mx)
    {
        for(int i = 1;i < k;i++)
        {
            if(a[i] == mx)
            {
                num++;
            }
        }
        cout << num + 1 << endl;
        return 0;
    }
    for(int i = 1;i <= n;i++)
    {
        if(a[i] == mx)
        {
            num++;
            continue;
        }
        if(a[i] >= a[k] && i < k)
        {
            d[++tot] = a[i] - a[k] + 1;
        }
        if(a[i] > a[k] && i > k)
        {
            d[++tot] = a[i] - a[k];
        }
    }
    num += tot;
    sort(d + 1,d + 1 + tot);
    for(int i = 1;i <= tot;i++)
    {
        if(m >= d[i])
        {
            m -= d[i];
            num--;
        }
    }
    cout << num + 1 << endl;
    return 0;
}

七.数列染色

题目链接:https://www.lanqiao.cn/problems/21219/learning/

1.题目讲解

2.代码实现

cpp 复制代码
#include <iostream>
using namespace std;

typedef long long LL;
const int N = 1e5 + 10;

int n, k, a[N];
LL f[N], q[N], h = 1, t;

int main()
{
    cin >> n >> k;
    for (int i = 1; i <= n; i++) 
        cin >> a[i];

    f[1] = a[1];
    for (int i = 2; i <= n; i++)
    {
        // 维护单调队列:队尾弹出比当前值大的元素
        while (h <= t && f[q[t]] >= f[i - 1]) 
            t--;
        // 当前元素下标入队
        q[++t] = i - 1;
        // 队头弹出超出窗口左边界的元素
        if (h <= t && q[h] < i - k - 1) 
            h++;

        // 状态转移:取窗口内最小值 + 当前a[i]
        f[i] = f[q[h]] + a[i];
    }

    cout << f[n] << endl;

    return 0;
}

八.正方形构造

题目链接:https://www.lanqiao.cn/problems/21210/learning/

1.题目讲解

2.代码实现

cpp 复制代码
#include <iostream>
using namespace std;

typedef long long LL;
const int N = 1010, mod = 1e9 + 7;

int n, m = 1000;
LL cnt[N];

// 排列数 A(n, m) 函数
LL A(LL n, LL m)
{
    LL ret = 1;
    for (int i = 0; i < m; i++) 
        ret = ret * (n - i) % mod;
    return ret;
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        int x; cin >> x;
        cnt[x]++;
    }

    LL ret = 0;

    // 情况1:选出两个不同的数,各取2个,再排列
    for (int i = 1; i <= m; i++)
    {
        if (cnt[i] < 2) continue;
        for (int j = i + 1; j <= m; j++)
        {
            if (cnt[j] < 2) continue;
            ret = (ret + A(cnt[i], 2) * A(cnt[j], 2) % mod) % mod;
        }
    }
    ret = ret * 2 % mod;

    // 情况2:选出相同的数,取4个排列
    for (int i = 1; i <= m; i++)
    {
        if (cnt[i] < 4) continue;
        ret = (ret + A(cnt[i], 4)) % mod;
    }

    cout << ret << endl;

    return 0;
}

九.杨辉三角

题目链接:https://www.lanqiao.cn/problems/21212/learning/

1.题目讲解

2.代码实现

cpp 复制代码
#include <iostream>
#include <map>
using namespace std;

typedef long long LL;
const int N = 1e5 + 10;

int m, cnt[N];
map<int, int> mp;

int main()
{
    cin >> m;
    for (LL n = 2; n <= m; n++)
    {
        LL c = 1;
        for (LL k = 1; k <= n / 2; k++)
        {
            // C(n, k)
            c = c * (n - k + 1) / k;
            if (c > N) break; // 剪枝

            if (k * 2 == n) 
                cnt[c] += 1;
            else 
                cnt[c] += 2;
        }
    }

    for (int i = 2; i <= m; i++)
        mp[cnt[i]]++;

    for (auto& t : mp)
        cout << t.first << " " << t.second << endl;

    return 0;
}

十.整齐的数

题目链接:https://www.lanqiao.cn/problems/21209/learning/

1.题目讲解

2.代码实现

cpp 复制代码
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

typedef long long LL;
const int N = 20, M = 210;

LL a[N], cnt, n, m;
LL f[N][N][M];

LL dfs(int pos, int prev, int sum, bool limits, bool zero)
{
    if (!pos) 
        return 1;
    if (!limits && !zero && ~f[pos][prev][sum]) 
        return f[pos][prev][sum];

    LL ret = 0;
    LL up = limits ? a[pos] : 9;

    for (int i = 0; i <= up; i++)
    {
        if (zero)
        {
            ret += dfs(pos - 1, i, sum, limits && (i == a[pos]), zero && !i);
        }
        else if (abs(i - prev) + sum <= m)
        {
            ret += dfs(pos - 1, i, sum + abs(i - prev), limits && (i == a[pos]), zero && !i);
        }
    }

    if (!limits && !zero) 
        f[pos][prev][sum] = ret;
    return ret;
}

int main()
{
    cin >> n >> m;

    memset(f, -1, sizeof(f));
    while (n)
    {
        a[++cnt] = n % 10;
        n /= 10;
    }

    cout << dfs(cnt, 0, 0, 1, 1) << endl;

    return 0;
}
相关推荐
码完就睡1 小时前
C语言——结构体的内存存储规则
c语言·开发语言
沈浩(种子思维作者)1 小时前
物理的本质是数学,还是数学只是描述物理的方便之语?
人工智能·python·算法
yoyo_zzm1 小时前
四大编程语言对比:C/C++/C#/PHP
c++·c#·php
程序员zgh1 小时前
AUTOSAR CP 之 配置、开发流程、工具链 解析
c语言·开发语言·c++·系统架构·汽车
黎阳之光1 小时前
数智孪生,全景可视——黎阳之光透明仓库,重构智慧仓储新范式
大数据·人工智能·算法·安全·数字孪生
小小测试开发1 小时前
NVIDIA SANA-WM:2.6B 开源世界模型,单卡 H100 生成 1 分钟 720p 视频
c++·音视频·mfc
生成论实验室2 小时前
WOLM认知引擎:为系统赋予“知止”的生命本能——一套确定性、内生安全的通用认知决策内核
人工智能·算法·机器学习·自动驾驶·安全架构
Romantic_love_2 小时前
【类和对象 :上篇】
c++·学习
黎阳之光2 小时前
智慧公安视频孪生平台:构建全域治安防控可视化体系
大数据·人工智能·算法·安全·数字孪生