0
0

More than 1 year has passed since last update.

Educational Codeforces Round 115 B. Groups

Last updated at Posted at 2021-10-12

題意

  • あなたは異なる曜日(月曜から金曜の5日間)の2日に授業をすることにします。
  • $2n$人の生徒がいます。それぞれの生徒は授業を受けられる日を1, 出られない日を0としてスケジュールを全員が提出しました。
  • あなたは各授業がn人ぴったりであるように授業のクラスを分けたいです。
  • 各生徒は2つ授業両方には参加できません。

こう考えた

総当たりをします。各曜日を総当たりするには、

for i in range(5):
 for j in range(i+1, 5):
  # i と jの2つの曜日を選んだ

とすればよいです。

さて、i,jを定めたとき、以下を求めることができます。

numboth: iもjも出席できるの学生
numi: iだけに参加できる学生
numj: jだけに参加できる学生
numng: 両方参加できない学生

この時、次のように順に考えます。

  • まず、合計の人数が$2n$で$n$人に分けたいのだから$numng$が1人以上いる場合、NGです。(絶対にn人に満たない授業ができてしまいます。)
  • numiかnumjがnをよりも多い場合NGです。(もう片方の授業はn人未満になります)
  • それ以外の場合、絶対に成立します。$numi+numj+numboth = 2n$なので、$numi + x = n$となる$0 \leq x \leq n$は必ず存在し、$numj + (numboth - x) = n$は明らかです。

この処理をすべてのi,jに対して行い、1つでもOKならYESです。すべてのi,jについて成り立たないならNOです。

実装

def do():
    n = int(input()) // 2
    dat = []
    for i in range(2*n):
        dat.append(list(map(int, input().split())))
    for i in range(5):
        for j in range(i+1, 5):
            cani = canj = canboth = canno = 0
            for ind in range(2*n):
                if dat[ind][i] == dat[ind][j] == 1: canboth += 1
                elif dat[ind][i] == 1: cani += 1
                elif dat[ind][j] == 1: canj += 1
                else: canno += 1
            if canno > 0: continue
            if cani > n or canj > n: continue
            print("YES")
            return
    print("NO")
q = int(input())
for _ in range(q):
    do()

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0