当前位置: 首页 > news >正文

acwing 每日一题4888. 领导者

目录

题目简述:

思路梳理:

总代码:


https://www.acwing.com/problem/content/description/4891/

题目简述:

有两个品种的奶牛,分别为G和H,我们要在每个品种中各找一头牛当领导者,最后输出全部的可能方案,当领导牛是有条件的,要么在其管辖范围内有其品种的全部牛,要不在其管辖范围内有另一品种牛的领导者;

思路梳理:

有一种很明显的思路:先判断在每头牛的管辖范围内有没有其品种的全部牛,如果有就代表这个牛能当领导牛,标记一下,在判断第二条件,因为第二个条件是依附于第一个条件而存在的,最后找出两种牛的各个领导牛的可能数,相乘即为答案;

这个思路很简单,但是代码实现较为复杂且易错,处理这些条件需要开三个前缀和数组,四个计数器,一个状态数组。。。(可能有其他更好的思路,但我只想到了这一个())

需要注意的是:分类讨论计算当前品种的奶牛的前缀和时,也要更新另一品种的前缀和,让另一品种的前缀和等于前一状态即可,要不会导致状态丢失(前缀和为0);【我因为这个调试了半天】

总代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
// s1 用于记录前缀位置中 'G'的数量,s2 用于记录前缀位置中 'H'的数量
// s3 用于记录领导牛的奶牛数量的前缀和
int s1[N], s2[N], s3[N]; 
int n, cnt1, cnt2, res1, res2; 
// n:奶牛总数;cnt1:根西牛('G')的总数;cnt2:荷斯坦牛('H')的总数
// res1:满足条件的根西牛领导者的可选数量;res2:满足条件的荷斯坦牛领导者的可选数量
char s[N]; // 存储每头奶牛的品种('G' 或 'H')
int a[N]; 
bool b[N]; // 标记某头奶牛是否已满足成为领导者的条件(条件一)

int main() {
    cin >> n; // 输入奶牛的总数
    // 遍历每头奶牛,统计品种信息并计算前缀和
    for (int i = 1; i <= n; i++) {
        cin >> s[i]; // 输入第 i 头奶牛的品种
        if (s[i] == 'G') {
            // 更新根西牛的前缀数量,荷斯坦牛前缀数量不变,根西牛总数加 1
            s1[i] = s1[i - 1] + 1; 
            s2[i] = s2[i - 1]; 
            cnt1++; 
        }
        if (s[i] == 'H') {
            //更新荷斯坦牛的前缀数量,根西牛前缀数量不变,荷斯坦牛总数加 1
            s2[i] = s2[i - 1] + 1; 
            s1[i] = s1[i - 1]; 
            cnt2++; 
        }
    }

    // 处理每头奶牛写下的名单范围,判断是否满足条件一(名单包含其品种所有奶牛)
    for (int i = 1; i <= n; i++) {

        cin >> a[i]; 
        
        if (s[i] == 'G') {
            // 判断该根西牛的名单是否包含所有根西牛
            if (s1[a[i]] - s1[i - 1] == cnt1) { 
                res1++; // 根西牛领导者可选数量加 1
                b[i] = 1; // 标记该奶牛已满足条件
                s3[i] = s3[i - 1] + 1; // 更新满足条件的奶牛数量前缀和
            } else {
                s3[i] = s3[i - 1]; // 不满足条件,前缀和不变
            }
        }

        if (s[i] == 'H') {
            // 判断该荷斯坦牛的名单是否包含所有荷斯坦牛
            if (s2[a[i]] - s2[i - 1] == cnt2) { 
                res2++; // 荷斯坦牛领导者可选数量加 1
                b[i] = 1; // 标记该奶牛已满足条件
                s3[i] = s3[i - 1] + 1; // 更新满足条件的奶牛数量前缀和
            } else {
                s3[i] = s3[i - 1]; // 不满足条件,前缀和不变
            }
        }
    }

    // 处理未标记的奶牛,判断是否满足条件二(名单包含另一品种的领导者)
    for (int i = 1; i <= n; i++) {
        if (b[i]) continue; // 已满足条件一,跳过
        // 判断该奶牛的名单中是否包含已满足条件的奶牛(即是否包含另一品种的领导者)
        if (s3[a[i]] - s3[i - 1] > 0) { 
            if (s[i] == 'G') res1++; // 根西牛满足条件二
            else res2++; // 荷斯坦牛满足条件二
        }
    }

    cout << res1 * res2 << endl; // 输出满足条件的选择方案数量(根西牛与荷斯坦牛可选领导者数量的乘积)
    return 0;
}

细节探讨:

最后判断条件二的时候并没有分类讨论,满足条件一的奶牛是否和当前所枚举的奶牛相同,这样可以吗?答案是可以的;

 

例如此图,第2个G符合条件1,但它一定不会出现在第3个G的前缀和(s3[4]-s3[3-1])里,且题目数据里也标注了i<=ei<=n,所以无需担心判断条件2时,前缀和中有和自身相同品种的牛~~~~

(细不细~) 

相关文章:

  • 19款超级华丽动画的图片轮播HTML5+CSS3模板源码
  • Linux驱动开发--SPI子系统
  • Electron应用生命周期全解析:从启动到退出的精准掌控
  • python 将mkv格式视频转换成mp4格式
  • 禅道品牌全面战略升级:开创项目管理国产化替代新格局
  • VLAN 聚合
  • 最短路径题目练习
  • 内核、进程和线程---操作系统
  • Audacity Nyquist插件开发:插件标头详解
  • pnpm node_modules 高效删除
  • BAPLIE船图文件:EDI 核心字段与应用场景解析
  • 一维码与二维码的全面区别及选择指南:详解优劣势与应用
  • HCIP VRRP MSTP 交换综合实验
  • 小测验——合并多个网格文件调用相机参数进行适配
  • Baklib企业CMS的核心组成是什么?
  • 第J8周:Inception v1算法实战与解析
  • 【强化学习】基于深度强化学习的微能源网能量管理与优化策略研究【Python】
  • 2019 CCF CSP-S2.Emiya 家今天的饭
  • [识记]Mysql8 远程授权
  • Spring Boot 实战:MD5 密码加密应用全解析
  • 第十一届世界雷达展开幕,尖端装备、“大国重器”集中亮相
  • 中国情怀:时代记录与家国镜相|澎湃·镜相第三届非虚构写作大赛征稿启事
  • 普京调整俄陆军高层人事任命
  • 把中国声音带向世界,DG和Blue Note落户中国
  • 奥迪车加油时频繁“跳枪”维修两年未解决,4S店拒退换:可延长质保
  • 举牌代跳明码标价、留言不堪入目,未成年人擦边短视频成引流利器