USACO历年青铜组真题解析 | 2023年1月Leaders

学习C++从娃娃抓起!记录下USACO(美国信息学奥赛)备考青铜组别比赛学习过程中的题目,记录每一个瞬间。

附上汇总贴:USACO历年青铜组真题解析 | 汇总-CSDN博客


【题目描述】

FJ 有 N 头奶牛,每一头奶牛的品种是根西岛 G 或荷斯坦 H 中的一种。

每一头奶牛都有一个名单,第 i 头奶牛的名单上记录了从第 i 头奶牛到第 Ei 头奶牛的所有奶牛。

每一种奶牛都有且仅有一位“领导者”,对于某一头牛 i,如果它能成为“领导者”仅当它满足以下条件的至少一个

  • 其记录的名单上包含它的品种的所有奶牛。
  • 其记录的名单上记录了另一品种奶牛的“领导者”。

请求出有多少对奶牛可能成为两种奶牛的领导者,保证存在至少一种。

【输入】

The first line contains N.

The second line contains a string of length N , with the ith character denoting the breed of the i-th cow (G meaning Guernsey and H meaning Holstein). It is guaranteed that there is at least one Guernsey and one Holstein.

The third line contains E1⋯EN.

【输出】

Output the number of possible pairs of leaders.

【输入样例】

4
GHHG
2 4 3 4

【输出样例】

1

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int n, e[200005], firstH=0, lastH=0, firstG=0, lastG=0, ansG[200005]={0}, ansH[200005]={0}, cntG=0, cntH=0;  // ans1记录该头牛是否包含所有牛
int leaderG=0, leaderH=0;
string s;
int main()
{
    cin >> n;  // 输入n
    cin >> s;  // 输入字符串(方便查找)
    s = " " + s;  // 因为起始位置为1,所以在字符串前面加个空格
    for (int i=1; i<=n; i++) {  // 遍历n头奶牛
        cin >> e[i];  // 记录每头奶牛的名单
    }
    firstG = s.find('G');  // 获取第一头G奶牛的位置
    lastG = s.rfind('G');  // 获取最后一头G奶牛的位置
    firstH = s.find('H');  // 获取第一头H奶牛的位置
    lastH = s.rfind('H');  // 获取最后一头H奶牛的位置
    for (int i=1; i<=n; i++) {  // 遍历所有奶牛,找到包含所有同种品种奶牛的位置
        if (s[i]=='G') {  // 找G牛
            if (i<=firstG && e[i]>=lastG) {  // 如果包含所有同种品种的奶牛
                ansG[i]=1;  // 标记为1
                leaderG = i;  // 并且记录位置(G中有且只有一头头牛)
            }
        }
        if (s[i]=='H') {  // 找H牛
            if (i<=firstH && e[i]>=lastH) {  // 如果包含所有同品种的奶牛
                ansH[i]=1;  // 标记为1
                leaderH = i; // 并记录位置(H中也有且只有一头头牛)
            }
        }
    }
    for (int i=1; i<=n; i++) {  // 再次遍历n头奶牛
        if (s[i]=='G') {  // 查找满足条件:名单上记录另一品种奶牛的领导者
            if (i<=leaderH && e[i]>=leaderH) ansG[i]= 1;  // 满足条件的标记为1
        }
        if (s[i]=='H') {  // 同上
            if (i<=leaderG && e[i]>=leaderG) ansH[i]= 1;
        }
    }
    for (int i=1; i<=n; i++) {  // 最后将G牛和H牛种中标记为1的牛进行统计
        if (ansG[i]==1) cntG++;
        if (ansH[i]==1) cntH++;
    }
    cout << cntG*cntH << endl;  // 将两者统计结果相乘,得到方案数
    return 0;
}

【运行结果】

4
GHHG
2 4 3 4
1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值