結果
| 問題 |
No.1830 Balanced Majority
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-02-17 23:50:07 |
| 言語 | Scala(Beta) (3.6.2) |
| 結果 |
AC
|
| 実行時間 | 736 ms / 2,000 ms |
| コード長 | 3,428 bytes |
| コンパイル時間 | 13,151 ms |
| コンパイル使用メモリ | 270,296 KB |
| 実行使用メモリ | 78,384 KB |
| 平均クエリ数 | 11.69 |
| 最終ジャッジ日時 | 2024-06-29 07:54:30 |
| 合計ジャッジ時間 | 30,875 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 25 |
ソースコード
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
import scala.io.StdIn.*
import scala.util.chaining.*
import scala.math.*
import scala.util._
trait Judge:
val size: Int
def askDiffLeft(until: Int): Int
def askDiffRight(from: Int): Int
def answer(from: Int, until: Int): Unit
class RandomJudge(override val size: Int, generator: Random) extends Judge:
val state = Array.tabulate(size){_ & 1}.pipe(generator.shuffle)
val sum = state.clone().tap{array =>
for i <- 1 until size do
array(i) += array(i - 1)
}
private var count: Int = 0
def currentCount = count
override def askDiffLeft(until: Int): Int =
if until == 0 then
0
else
count += 1
val one = sum(until - 1)
val zero = until - one
one - zero
override def askDiffRight(from: Int): Int =
if from == size then
0
else if from == 0 then
size / 2
else
count += 1
val one = size / 2 - sum(from - 1)
val zero = size - from - one
one - zero
override def answer(from: Int, until: Int) =
if from > 0 then
require((sum(until - 1) - sum(from - 1)) * 2 == until - from)
else
require(sum(until - 1) * 2 == (until - from))
require(count <= 20)
require((size / 2 until size).contains(until - from))
class SystemJudge(override val size: Int) extends Judge:
private def ask(to: Int): Int =
if to < 0 then
0
else if to + 1 == size then
size / 2
else
println(s"? ${to + 1}")
readLine.toInt
override def askDiffLeft(until: Int): Int =
val one = ask(until - 1)
val zero = until - one
one - zero
override def askDiffRight(from: Int): Int =
val one = size / 2 - ask(from - 1)
val zero = size - from - one
one - zero
override def answer(from: Int, until: Int) =
println(s"! ${from + 1} $until")
def test(size: Int, seed: Int): Int =
val random = Random(seed)
val judge = RandomJudge(size, random)
solve(size, judge)
judge.currentCount
def solve(size: Int, judge: Judge) =
val left = size / 4
val right = left + size / 2
val leftDiff = judge.askDiffLeft(left)
val rightDiff = judge.askDiffRight(right)
if leftDiff == 0 then
judge.answer(left, size)
else if rightDiff == 0 then
judge.answer(0, right)
else if leftDiff + rightDiff == 0then
judge.answer(left, right)
else if leftDiff.sign * rightDiff.sign > 0 then
var min = left
var max = right
while min < max do
val mid = (min + max) >> 1
val diff = judge.askDiffLeft(mid)
if diff.sign == leftDiff.sign then
min = mid + 1
else
max = mid
if max >= size / 2 then
judge.answer(0, max)
else
judge.answer(max, size)
else if leftDiff.abs < rightDiff.abs then
var min = right
var max = size
while min < max do
val mid = (min + max) >> 1
val diff = judge.askDiffRight(mid)
if (diff + leftDiff).sign * rightDiff.sign > 0 then
min = mid + 1
else
max = mid
judge.answer(left, max)
else
var min = 0
var max = left
while min < max do
val mid = (min + max) >> 1
val diff = judge.askDiffLeft(mid)
if (diff + rightDiff).sign * leftDiff.sign >= 0 then
max = mid
else
min = mid + 1
judge.answer(max, right)
@main def main =
val size = readLine.toInt
solve(size, SystemJudge(size))