結果

問題 No.507 ゲーム大会(チーム決め)
ユーザー codewow1codewow1
提出日時 2019-12-28 00:09:09
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 229 ms / 3,000 ms
コード長 2,968 bytes
コンパイル時間 162 ms
コンパイル使用メモリ 82,440 KB
実行使用メモリ 135,036 KB
最終ジャッジ日時 2024-10-09 17:44:55
合計ジャッジ時間 4,541 ms
ジャッジサーバーID
(参考情報)
judge4 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 114 ms
78,508 KB
testcase_01 AC 116 ms
78,520 KB
testcase_02 AC 113 ms
78,520 KB
testcase_03 AC 37 ms
52,400 KB
testcase_04 AC 115 ms
78,600 KB
testcase_05 AC 114 ms
78,724 KB
testcase_06 AC 37 ms
52,868 KB
testcase_07 AC 164 ms
85,512 KB
testcase_08 AC 90 ms
81,512 KB
testcase_09 AC 179 ms
127,516 KB
testcase_10 AC 182 ms
115,480 KB
testcase_11 AC 205 ms
128,284 KB
testcase_12 AC 177 ms
127,000 KB
testcase_13 AC 229 ms
135,036 KB
testcase_14 AC 225 ms
131,776 KB
testcase_15 AC 223 ms
133,432 KB
testcase_16 AC 220 ms
133,048 KB
testcase_17 AC 118 ms
78,496 KB
testcase_18 AC 117 ms
78,620 KB
testcase_19 AC 111 ms
78,828 KB
testcase_20 AC 112 ms
78,876 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys

# 入力を受け取る
input = sys.stdin.readline
N, M = map(int, input().split())

As = []
for i in range(N):
  As.append(int(input()))

K = As[0]

As = As[1:]

As.sort()

if N == 2*M:
  print(As[0])
  exit()

#### 二分探索 O(logN) ####
## ソート済み配列sorted_arrの中にTrueとFalseの境界が存在
## すべてTrue または すべてFalseもありうる
def binary_search(sorted_arr, type="max"):
  # 境目のうちTrue側のindexを返す。すべてTrueまたはFalseのときは-1を返す
  # 加えてindex=0の真偽値を返す
  # ref : 条件式に用いるための変数

  def binary_TF(sorted_arr, index):
    # 条件を設定する
    # 対象となる配列、基準となる配列要素(真ん中)、条件判定に使う基準

    K_pair = K + sorted_arr[index]

    As_after = As[0:index] + As[index+1:]

    Ps = []

    for i in range(M):
      pair_tmp = As_after[-1 - i] + As_after[-2*M + i]
      Ps.append(pair_tmp)

    if min(Ps) <= K_pair:
      return True
    else:
      return False

  # 配列の一番最初と最後の要素がそれぞれ条件を満たすかどうか
  TF_left = binary_TF(sorted_arr, 0)
  TF_right = binary_TF(sorted_arr, len(sorted_arr)-1)

  if TF_left == TF_right:
    # 両方が条件を満たす(または両方が条件を満たさない)場合は終了
    # 2番目の返り値に、両方の値(TrueかFalse)が入る
    if TF_left == True:
      if type == "max":
        return len(sorted_arr)-1, True
      elif type == "min":
        return 0, True
    else:
      return None, False
  else:
    if TF_right:
      # 最後の要素がTrueの場合、
      ok = len(sorted_arr)    # 末尾側をTrueにし、
      ng = -1                 # 先頭側をFalseにする
    else:
      # 最初の要素がTrueの場合、
      ok = -1                 # 先頭側をTrueにし、
      ng = len(sorted_arr)    # 末尾側をFalseにする

  while (abs(ok - ng) > 1):   # 境目が確定するまで繰り返す
    mid = int((ok + ng)/2)
    if binary_TF(sorted_arr, mid):
      ok = mid
    else:
      ng = mid
  # ok : 境目のうち、True側の配列インデックス
  # 2番目の引数は途中終了の場合との整合性をとるため。
  return ok, True

import pdb

# pdb.set_trace()

# K君を除いたスコアの最大値と最小値の範囲で二分探索する
ans = binary_search(As, type="min")[0]

if ans == None:
  print(-1)
else:
  print(As[ans])
# ある相方のスコアに対して、
# そのスコアを抜いた残りのスコア配列の中から
# 大きい順に2M個の数字を取り出す
# 取り出した2M個の数字群に対して、
# (1番大きい数字+1番小さい数字)+(2番目に大きい数字+2番目に小さい数字)+・・・
# を求めて、それぞれP1, P2, ... とする
# K君と相方のスコア合計値がPiの最小値よりも大きければOK
0