第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;
}
相关推荐
骑着蜗牛撵大象327几秒前
558 万美元训出 671B 模型:DeepSeek-V3 算法与系统的协同拆解
分布式·算法·moe·deepseek-v3·mla·fp8训练
Eyfcom3 分钟前
〖阶段性回顾〗物流系统架构与算法的 Day 1-5 知识图谱与实战答疑
算法·系统架构·知识图谱·物流管理系统·快递管理系统
xunberg8 分钟前
【Agent 生产化手记-02】Agent 怎么向人提问
人工智能·算法·架构
海绵宝宝转agent13 分钟前
Leetcode二叉树算法个人理解
笔记·学习·算法·leetcode·深度优先
pjj1985438 分钟前
YOLO 目标检测算法系列梳理:从 V1 到 V5 的原理演进
算法·yolo·目标检测
kiracrimson1 小时前
STL:List的使用和模拟实现
开发语言·c++·list
二十七日秋1 小时前
算法刷题笔记「Day 1|四道 OJ 入门题里的深坑」
c语言·汇编·数据结构·c++·笔记·python·算法
晚风叙码1 小时前
Linux 进程概念(下):程序地址空间与虚拟内存
linux·服务器·算法
流年如夢1 小时前
继承与多态_继承篇
c++·继承·面向对象·c++进阶
silvamux_2 小时前
微头条爆款体平台适配实测:把交付要求变成可计算的指标
java·线性代数·算法·决策树·矩阵