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

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时,前缀和中有和自身相同品种的牛~~~~

(细不细~) 


http://www.kler.cn/a/612960.html

相关文章:

  • EMC知识学习三
  • firewall-cmd添加访问规则
  • Next.js 中间件鉴权绕过漏洞 (CVE-2025-29927) 复现利用与原理分析
  • 标准库中有uint32_t类型吗?
  • Pytorch学习笔记(十六)Image and Video - Transfer Learning for Computer Vision Tutorial
  • Mysql-DML
  • Linux命令大全:从入门到高效运维
  • Mac: 运行python读取CSV出现 permissionError
  • 【LeetCode 题解】数据库:180. 连续出现的数字
  • 提示词应用:IT模拟面试
  • CSS学习笔记5——渐变属性+盒子模型阶段案例
  • 构建高可用性西门子Camstar服务守护者:异常监控与自愈实践
  • k近邻算法K-Nearest Neighbors(KNN)
  • office_word中使用宏以及DeepSeek
  • 如何让DeepSeek-R1在内网稳定运行并实现随时随地远程在线调用
  • Redis原理:setnx
  • 基于深度学习的图像超分辨率技术研究与实现
  • 解决 Apache Kylin 加载 Hive 表失败的问题:深入分析与解决方案
  • 逗万DareWorks|创意重构书写美学,引领新潮无界的文创革命
  • 从物理学到机器学习:用技术手段量化分析职场被动攻击行为