ACM-ICPC 2017 模擬国内予選: C. クイズ
solution
各解答者について取りうる得点の最大値と最小値を求めればよい。$O(M + N^2)$。
得点の最大値は単に足し合わせればよい。 最小値は$0$というわけにはいかず、自分しか答えられない問題には必ず答えねばならない。 そのようにして最大最小を求め、全解答者対での得点の差の最大値$+1$が答え。
implementation
#include <cstdio>
#include <vector>
#define repeat(i, n) for (int i = 0; (i) < int(n); ++(i))
using namespace std;
template <class T> inline void setmax(T & a, T const & b) { a = max(a, b); }
int main() {
while (true) {
int n, m; scanf("%d%d", &n, &m);
if (n == 0 and m == 0) break;
vector<int> s_max(n);
vector<int> s_min(n);
repeat (i, m) {
int s, k; scanf("%d%d", &s, &k);
repeat (j, k) {
int c; scanf("%d", &c); -- c;
s_max[c] += s;
if (k == 1) {
s_min[c] += s;
}
}
}
int result = 0;
repeat (i, n) repeat (j, n) if (i != j) {
setmax(result, s_max[j] - s_min[i] + 1);
}
printf("%d\n", result);
}
return 0;
}