Official
A - 料理コンテストと食材 / Cooking Contest and Ingredients Editorial
by
A - 料理コンテストと食材 / Cooking Contest and Ingredients Editorial
by
kyopro_friends
初心者の方へ
- AtCoder をはじめたばかりで何をしたらよいか分からない方は、まずは practice contest の問題A「Welcome to AtCoder」を解いてみてください。基本的な入出力の方法が載っています。
- また、プログラミングコンテストの問題に慣れていない方は、AtCoder Beginners Selection の問題をいくつか解いてみることをおすすめします。
- C++入門 AtCoder Programming Guide for beginners (APG4b) は、競技プログラミングのための C++ 入門用コンテンツです。
- Python入門 AtCoder Programming Guide for beginners (APG4bPython) は、競技プログラミングのための Python 入門用コンテンツです。
問題は次の2つのパートに別れます
- 上位 \(K\) 人を求める
- 上位 \(K\) 人に共通する得意食材の個数を求める
上位 \(K\) 人を求める
得点と番号の組 \((V_i,i)\) を問題文の指示通り「得点の降順、タイなら番号の昇順」という比較関数でソートすることで上位から順に並べ替えることができます。
この比較関数を実装してもよいですが、\((V_i, -i)\) を降順にソートすることで同じ効果を得ることができます。
今回ように「1つ目の降順、タイなら2つ目の昇順でソート」と昇順と降順が混ざっている場合は、適切に \(-1\) 倍することで、通常の昇順/降順ソートで行うことができます。
上位 \(K\) 人に共通する得意食材の個数を求める
各食材に対して、それが上位 \(K\) 人の得意食材として登場する回数を求めます。登場回数が \(K\) であることが、全員に共通する得意食材であることと同値であるため、そのような食材の個数を求めればよいです。
実装例 (C++)
#include<bits/stdc++.h>
using namespace std;
int main(){
int n, m, k;
cin >> n >> m >> k;
vector<int>v(n);
vector<int>c(n);
vector<vector<int>>t(n);
for(int i=0; i<n; i++){
cin >> v[i] >> c[i];
vector<int>ti(c[i]);
for(int j=0; j<c[i]; j++) cin >> ti[j];
t[i] = ti;
}
// (v[i], -i) を降順ソート
vector<pair<int,int>>vi(n);
for(int i=0; i<n; i++) vi[i] = {v[i], -i};
sort(vi.rbegin(), vi.rend());
// 食材の登場回数をカウント
vector<int>count(m+1);
for(int p=0; p<k; p++){
int i = - vi[p].second;
for(int j=0; j<c[i]; j++){
count[t[i][j]]++;
}
}
// 登場回数が K である食材の個数
int ans = 0;
for(int i=1; i<=m; i++){
if(count[i] == k){
ans++;
}
}
cout << ans << endl;
}
実装例 (Python)
N, M, K = map(int, input().split())
V = []
T = []
for _ in range(N):
v, c, *t = map(int, input().split())
V.append(v)
T.append(t)
# (v[i], -i) を降順ソート
VI = [(V[i], -i) for i in range(N)]
VI.sort(reverse=True)
# 食材の登場回数をカウント
count = [0] * (M+1)
for _, minus_i in VI[:K]:
i = - minus_i
for t in T[i]:
count[t] += 1
# 登場回数が K である食材の個数
print(count.count(K))
posted:
last update:
