IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【计蒜客模拟赛系列】-计蒜客8月普及组模拟赛 -> 正文阅读

[数据结构与算法]【计蒜客模拟赛系列】-计蒜客8月普及组模拟赛

提前:本文中部分代码和思路有借鉴或摘抄计蒜客官方题解

赛后总结

本次模拟赛的难度总算正常了些
个人战绩: 220/400,排名61 ,太弱了,一大堆AK爷
题目质量评价: 题目相比CSP-J还是简单了一些,比较友好,题目质量还是比较高的。个人觉得前两题题面写的非常长,但是提炼出来重点后,就会觉得非常简单,很锻炼大家的信息提取与概括能力;代码实现难度低,平均也就个三四十行左右。
考查知识点: T1、2模拟,T3动态规划,T4堆 (没考图和树算法?)

题解

T1 鲜奶贩卖

题目链接: https://nanti.jisuanke.com/t/56597
涉及知识点: 模拟
解题思路:
签到题。
直接根据题意降价并判断即可。
正解代码:

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

int x, h, y; //开始1000元,保质期h小时,预算y元 
bool f = false; //能不能买到

int main() {
    freopen("milk.in", "r", stdin);
    freopen("milk.out", "w", stdout);
    cin >> x >> h >> y;
    if (y >= x) {
        f = true;
        cout << 0 << endl;
    } else {
        for (int i = 1; i < h; i++) {
            x -= ceil(1.0 * i / 10);
            if (y >= x) {
                f = true;
                cout << i << endl;
                return 0;
            }
        }
    }
    if (!f) {
        cout << "IMPOSSIBLE" << endl;
    }
    return 0;
}

T2 滑冰游戏

题目链接: https://nanti.jisuanke.com/t/56598
涉及知识点: 模拟
解题思路:
相比T1,又增添了几分难度。
题面很长,概况一下:给定一个字符串为指定操作,可能向上、下、左、右移动,碰到'#'代表的墙壁或者'.'代表的冰块就停下。总分加上停下的这块方格的数值。也有可能打碎障碍冰块,冰块的方向一定是上一次操作的指定方向,且与人物相邻,打碎后原来冰块的地方分数为0
正解代码:
考场代码,可能有些冗杂,当然是可以优化的

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

//上下左右 敲碎
//U D L R  B
int n, m, x, y;
long long ans;
string opr;
char map[25][25];

int main() {
    freopen("game.in", "r", stdin);
    freopen("game.out", "w", stdout);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> map[i][j];
        }
    }
    cin >> x >> y >> m >> opr;
    for (int i = 0; i < m; i++) {
        if (opr[i] == 'B') { //按照上一次的操作来敲碎冰块
            if (opr[i - 1] == 'U') map[x - 1][y] = '0';
            if (opr[i - 1] == 'D') map[x + 1][y] = '0';
            if (opr[i - 1] == 'L') map[x][y - 1] = '0';
            if (opr[i - 1] == 'R') map[x][y + 1] = '0';
        }
        int mx = x, my = y; //用来探索的
        if (opr[i] == 'U') { //向上
            while (map[mx - 1][my] != '*' && map[mx - 1][my] != '#') {
                mx--;
            }
            ans += map[mx][my] - '0';
            x = mx, y = my;
            map[mx][my] = '0'; //将停留处清零
        }
        if (opr[i] == 'D') { //向下
            while (map[mx + 1][my] != '*' && map[mx + 1][my] != '#') {
                mx++;
            }
            ans += map[mx][my] - '0';
            x = mx, y = my;
            map[mx][my] = '0';
        }
        if (opr[i] == 'L') { //向左
            while (map[mx][my - 1] != '*' && map[mx][my - 1] != '#') {
                my--;
            }
            ans += map[mx][my] - '0';
            x = mx, y = my;
            map[mx][my] = '0';
        }
        if (opr[i] == 'R') { //向右
            while (map[mx][my + 1] != '*' && map[mx][my + 1] != '#') {
                my++;
            }
            ans += map[mx][my] - '0';
            x = mx, y = my;
            map[mx][my] = '0';
        }
    }
    cout << ans << endl;
    return 0;
}

T3 小明与春娇叠积木

考试时这题竟然爆零了,丢脸
题目链接: https://nanti.jisuanke.com/t/56599
涉及知识点: 动态规划
解题思路:
分档考虑。
30pts:
这个子任务给了我们一个条件,那就是他们俩的积木是相同的,也就是说我们可以只操作一个。
第一种写法,是暴力枚举计算积木最高高度,这里就不多说了。
第二种写法,是动态规划,设dp[i]是以i结尾的最高高度核心部分给出:

    for (int i = 1; i <= n; i++) {
        dp[i] = 1; //初始化
        for (int j = 1; j < i; j++) {
            if (a[j] + 1 == a[i] && dp[i] < dp[j] + 1) { //如果可以连得上并且dp[i]在更新后会更大
                dp[i] = dp[j] + 1;
            }
        }
        if (dp[i] > ans) {
            ans = dp[i]; //更新答案
        }
    }

60pts:
其实如果我们能够写出30pts的dp,我们就能照葫芦画瓢地对两座积木分别执行一样的dp操作。当然也可以用贪心做,我们设定i是一个序列的起点,如果枚举中与a[j]一样就把now/now2加1,最后得出的就是

for (int i = 1; i <= n; i++) {
    int now = i, now2 = i;
    for (int j = 1; j <= n; j++) {
        if (a[j] == now) {
            now++;
        }
        if (b[j] == now2) {
            now2++;
        }
    }
    if (ans < min(now, now2) - i) { //自己拿一组小数据模拟一下就知道了
        ans = min(now, now2) - i;
    }
}

100pts:
以动态规划的形式,计算两组积木的最高高度。
dp[i]为以i结尾的最高高度,则状态转移方程为dp[i] = max(dp[i], dp[i - 1] + 1)

T4 苹果售卖

题目链接: https://nanti.jisuanke.com/t/56642
涉及知识点: 暴力即枚举、正解即堆
解题思路:
现在是2021年8月29日23:34分,我想睡觉了,明天再继续更新
正解代码:
明天写

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

const int MAXN = 2 * 1e5 + 5;
int n, ans;
int dp[2][MAXN];

void make_dp (int dp[], int n) {
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        dp[x] = max(dp[x], dp[x - 1] + 1);
    }
    return;
}
int main() {
    freopen("juggle.in", "r", stdin);
    freopen("juggle.out", "w", stdout);
    cin >> n;
    make_dp(dp[0], n);
    make_dp(dp[1], n);
    for (int i = 1; i <= n; i++) {
        ans = max(ans, min(dp[0][i], dp[1][i]));
    }
    cout << ans << endl;
    return 0;
}

反思

1.T1、2这种简单题尽量能15min内解决,也就是说基础算法我必须熟记于心,说写就写(达成)
2.对于动态规划和后面一堆奇奇怪怪的知识点本蒟蒻还在不断学习中,未来也是必须要熟练的,那么在2021CSP中我就要选择拿尽可能多的部分分
2021CSP-J++!

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-30 12:27:46  更:2021-08-30 12:28:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:19:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码