AtCoder备赛冲刺必刷题(C++) | AtCoder AT_abc402_c Dislike Foods

本文分享的必刷题目是从蓝桥云课洛谷AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。

欢迎大家订阅我的专栏:算法题解:C++与Python实现

附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总


【题目来源】

AtCoder:C - Dislike Foods

【题目描述】

The AtCoder Restaurant uses N N N types of ingredients numbered from 1 1 1 to N N N.
AtCoder餐厅使用编号从 1 1 1 N N N N N N 种食材。

The restaurant offers M M M dishes numbered from 1 1 1 to M M M. Dish i i i uses K i K_i Ki types of ingredients, namely A i , 1 , A i , 2 , … , A i , K i A_{i,1},A_{i,2},…,A_{i,K_i} Ai,1,Ai,2,,Ai,Ki.
这家餐厅提供编号从 1 1 1 M M M M M M 道菜品。第 i i i 道菜使用了 K i K_i Ki 种食材,分别是 A i , 1 , A i , 2 , … , A i , K i A_{i,1},A_{i,2},…,A_{i,K_i} Ai,1,Ai,2,,Ai,Ki

Snuke currently dislikes all N N N ingredients. He cannot eat any dish that uses one or more ingredients he dislikes, and he can eat a dish that uses none of the disliked ingredients.
目前,Snuke 讨厌所有的 N N N 种食材。他不能吃任何使用了至少一种他讨厌的食材的菜品,但可以吃完全不包含这些讨厌食材的菜品。

Over the next N N N days, he will overcome his dislikes one ingredient per day. On day i i i, he overcomes ingredient B i B_i Bi, and from then on he no longer dislikes it.
在接下来的 N N N 天里,他每天会克服对一种食材的厌恶。第 i i i 天,他会克服对食材 B i B_i Bi 的厌恶,从此不再讨厌它。

For each i = 1 , 2 , … , N i=1,2,…,N i=1,2,,N, find:
对于每个 i = 1 , 2 , … , N i=1,2,…,N i=1,2,,N,计算:

  • the number of dishes at the AtCoder Restaurant that he can eat immediately after overcoming ingredient B i B_i Bi on day i i i.
    在AtCoder餐厅中,Snuke在第 i i i 天克服食材 B i B_i Bi 后立即可以享用的菜品数量。

【输入】

The input is given from Standard Input in the following format:

N M
K_1 A_{1,1} A_{1,2} ... A_{1,K_1}
K_2 A_{2,1} A_{2,2} ... A_{2,K_2}
.
.
.
K_M A_{M,1} A_{M,2} ... A_{M,K_M}
B_1 B_2 ... BN

【输出】

Print N N N lines. The k k k-th line should contain the answer for i = k i=k i=k.

【输入样例】

5 4
2 1 2
3 3 4 5
3 1 2 5
1 3
1 3 2 5 4

【输出样例】

0
1
2
3
4

【代码详解】

#include <bits/stdc++.h>
using namespace std;

const int N = 300005;  // 定义最大可能的人数
vector<int> dislike[N];  // 每个人不喜欢的食物列表
bool b[N];  // 未使用的布尔数组
int cnt[N];  // 记录每种食物还需要被多少人选择
int n, m, ans;  // n:人数, m:食物种类数, ans:当前满足条件的食物数

int main()
{
    // 输入人数n和食物种类数m
    cin >> n >> m;
    
    // 输入每种食物的不喜欢情况
    for (int i = 1; i <= m; i++) {
        int nums, x;  // nums:不喜欢该食物的人数, x:具体不喜欢的人
        cin >> nums;
        cnt[i] = nums;  // 初始化该食物需要被选择的人数
        while (nums--) {
            cin >> x;
            dislike[x].push_back(i);  // 记录这个人不喜欢的食物
        }
    }
    
    // 处理每个人的选择
    for (int i = 1; i <= n; i++) {
        int x;  // 当前人选择的食物
        cin >> x;
        
        // 更新该人不喜欢的食物的计数
        for (int j = 0; j < dislike[x].size(); j++) {
            int food = dislike[x][j];  // 不喜欢的食物编号
            cnt[food]--;  // 该食物需要被选择的人数减1
            if (cnt[food] == 0) ans++;  // 如果该食物不再需要被选择,则满足条件的食物数+1
        }
        
        // 输出当前满足条件的食物数
        cout << ans << endl;
    }

    return 0;
}

【运行结果】

5 4
2 1 2
3 3 4 5
3 1 2 5
1 3
1 3 2 5 4
0
1
2
3
4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值