Official

B - Tombola Editorial by sheyasutaka


実装方針

求めるものをかみ砕くと、以下のようにして実装できます。

  1. 各行について、その行にある \(W\) 個の値のうち \(B\) に入っているものの個数 (\(r_i\) とおく) を求める。
  2. \(r_1, \dots, r_H\) の最大値が答え。

ある値が \(B\) に入っているかどうかの判定は、\(B\) の要素 \(N\) 個をそれぞれ見て、探している値と等しいものが見つかれば Yes、すべて見ても見つからなければ No とすれば判定できます。 これをある行にある \(W\) 個の値それぞれについて判定し、\(r_i = 0\) で初期化した変数 \(r_i\) に対して存在する値ごとに \(1\) 増やせば、その行について求める個数が得られます。

以上のことを、ループや条件分岐といった言語機能を使って適切に実装することでこの問題を解くことができます。多重ループの実装に注意してください。

実装例 (C++)

#include <iostream>
using std::cin;
using std::cout;
using std::max;

int main (void) {
	// 入力
	int h, w, n;
	cin >> h >> w >> n;
	int a[h][w];
	for (int i = 0; i < h; i++) {
		for (int j = 0; j < w; j++) {
			cin >> a[i][j];
		}
	}
	int b[n];
	for (int i = 0; i < n; i++) {
		cin >> b[i];
	}
	
	// 答えを求め、変数 ans に記録
	int ans = 0;
	int rowcount[h]; 
	for (int i = 0; i < h; i++) {
		// 行 i における答えを求める (rowcount[i])
		rowcount[i] = 0;
		for (int j = 0; j < w; j++) {
			bool isfound = false; // a[i][j] が b に入っているとき true
			for (int k = 0; k < n; k++) {
				if (b[k] == a[i][j]) isfound = true;
			}
			if (isfound) {
				rowcount[i] += 1;
			}
		}
		// ans を更新する
		ans = max(ans, rowcount[i]);
	}

	// 出力
	cout << ans << "\n";

	return 0;
}

posted:
last update: