【洛谷刷题 | 第七天】

本系列文章我将总结我在刷算法题所用到的知识,如果你也在刷算法并且是新手,我相信这系列文章会很适合你。

今日题目:

【洛谷刷题 | 第七天】

    • 今日题目:
      • [1.CSP-J 2020 直播获奖(模拟,排序)](#1.[CSP-J 2020] 直播获奖(模拟,排序))
      • [2. 语言月赛 202404 道法考试(模拟,数组)](#2. [语言月赛 202404] 道法考试(模拟,数组))
    • 总结:

1.CSP-J 2020 直播获奖(模拟,排序)

链接:P7072 CSP-J 2020 直播获奖

依次读入 n 名选手成绩,每加入第 p 个选手后,用整数运算算出计划获奖人数

max(1,p×w÷100),取当前排名前该人数的最低成绩作为分数线,同分全部保留晋级,按顺序输出每一步实时分数线;成绩值域仅 0~600,n 最大10的5次方,禁止浮点计算防止精度出错。

案例:

cpp 复制代码
输入                                                        输出
10 60                                     200 300 400 400 400 500 400 400 300 300      
200 300 400 500 600 600 0 300 200 100

我当时想的是用set容器,因为它有自动排序的优点,但有一个致命的错误就是它会把重复的数据给删除掉,那能不能输入一个再重新排序,算出结果,先不说可不可以,这样算的复杂度特别高,当我们再次回看题目就可以发现,其实它的分数是有限制 的,而且数据不大,最高只有600,所有可以利用成绩值域仅 0~600的特点,用计数数组统计每个分数的出现次数,每录入一个选手成绩就更新计数数组,通过整数运算算出当前计划获奖人数,再从高分到低分累加统计人数,直至累加人数满足获奖要求,此时的分数即为实时分数线,依次输出即可。

题解:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int c[601];
int main()
{
    int n,w;
    cin>>n>>w;
    int a;
    int k;
    int line = 0;
    for(int i=1;i<=n;i++)
    {
        int sum =0;
        cin>>a;
        c[a]++;
        k = i*w/100;
        k = max(1,k);
        for(int j=600;j>=0;j--)
        {
            sum+=c[j];
            if(sum>=k){
                line = j;
                break;
            }
        }
          cout<<line<<" ";
    }
  
    
}

2. 语言月赛 202404 道法考试(模拟,数组)

链接:B3966 语言月赛 202404 道法考试

有 n 道题目,每题标准答案含 m 个知识点,依次读入每题标准答案与作答知识点,若每题作答完全包含对应全部标准答案知识点则得 2 分否则得 0 分,最后输出总分。

第一行两个整数 n 和 m,第 2∼n+1 行每行 m 个整数,第 i 行的内容表示第 i−1 题标准答案包含的知识点编号,保证单个题目的知识点编号没有重复,用空格隔开。从第 n+2 行到第 2n+1 行依次输入每题的作答内容,每行第一个整数是该题作答的知识点个数 l i l_i li,其后紧跟着 l i l_i li 个整数,代表这道题实际作答的所有知识点编号。

案例:

cpp 复制代码
输入                                       输出
2 2                                        2
1 3
4 6
2 1 4
7 1 2 3 4 6 7 8

这道题我最先想的是用容器把它们存起来,然后比较容器相不相同,但这样结果肯定是错的,因为只有作答和标准答案相等,这个方法才可以,但题干明确说明,只要作答包含了标准答案就是对的

其实这道题难的点就是想到用数组 这个方法,

可以先把每道题的标准答案存储在二维数组里,然后依次读取每道题的作答内容,用布尔数组标记作答过的知识点,接着检查这道题的所有标准答案知识点是否都被标记过,全部包含就加 2 分,最后输出总得分。

题解:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int a[1009][1009];
bool v[5009] = {false};
int main()
{
    int n,m;
    cin>>n>>m;
    int sum =0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
        }
    }
   
    int c;
    for(int i=1;i<=n;i++)
    {   
        memset(v, 0, sizeof(v));  
         int k;
         cin>>k;
        for(int j=0;j<k;j++)
        {
             cin>>c;
            v[c] = 1;
        }
         bool ok = 1;
        for(int j=1;j<=m;j++)
        {
            if(!v[a[i][j]]) {
                ok =0;
                break;
                
            }
        }
       if(ok) sum+=2;
    }
  cout<<sum;
}

总结:

今天的题目都是考察的代码思路 ,不能一上来就套用熟悉的容器和暴力排序,要先仔细审题观察数据特点。第一题直播获奖我一开始想用 set 自动排序,却忽略它会去重的缺陷,暴力排序又会超时,后来发现分数值域极小,改用计数数组高效统计;第二道法考试我最初想直接对比容器是否相等,误解题目只需包含而非完全一致,最后用标记数组判断元素包含关系。两道题都提醒做题要先避开思维定式,观察题目隐藏的数据范围与规则条件,选择更贴合题意、效率更高的解法,而不是盲目套用固定模板。

最后:

(这几天都去刷算法了,就没怎么更新,这次也非常幸运,做到了近几次最简单的题,所以就稳稳过了,把这份幸运分享给大家)

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

相关推荐
黄敬峰1 小时前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术2 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六5 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术6 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize7 小时前
初识DFS 与 BFS:递归、队列与图遍历
算法
罗西的思考20 小时前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
美团技术团队1 天前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
To_OC2 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC2 天前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
BadBadBad__AK2 天前
线段树维护区间 k 次方和
c++·数学·算法·stl