두 가지 비표준 문제 유형
대부분의 문제는 "입력 → 출력"이다. 그러나 정상급 셋에는 두 가지 변종이 자주 나온다.
- 인터랙티브(interactive): 정적 입력이 없고, 판정기와 대화 하며 질의를 던지고 답을 받는다. 질의 횟수에 상한이 있다.
- 구성(constructive): "조건을 만족하는 어떤 것을 직접 만들어라". 존재 증명이 곧 알고리즘이 된다.
이 강의는 인터랙티브에, 다음 강의는 구성에 집중한다.
인터랙티브의 기본 규약
- 질의를 출력하고 즉시 flush(버퍼 비우기). 안 하면 데드락.
- 판정기의 응답을 읽고 다음 질의를 정한다.
- 질의 횟수/형식 위반은 즉시 오답(WA/IE).
cout << "? " << x << endl; // endl이 flush를 포함
// 또는: cout << "? " << x << "\n"; cout.flush();
int res; cin >> res; // 판정기 응답
정보 이론 하한
인터랙티브의 질의 횟수 제한은 보통 정보량 으로 정해진다. 답의 후보가 \(N\)개고 한 질의가 \(b\)비트(예: yes/no는 1비트)를 주면, 최소
$$ \lceil \log_b N \rceil $$
번의 질의가 필요하다. 예: 1..N에서 숨은 수 맞히기, yes/no 질의 → \(\lceil \log_2 N \rceil\). 이 하한을 달성 하는 전략(이분 탐색)을 설계한다.
적응적 판정기(adaptive adversary)
가장 까다로운 점: 많은 인터랙티브 판정기는 적응적이다. 즉 답을 미리 고정하지 않고, 너의 질의에 가장 불리하게 답을 나중에 정한다. 단, 이미 한 답과 모순되지 않는 한도 내에서.
비유: 숨은 수 맞히기에서 판정기가 수를 안 정해 두고, 매번 "아직 가능한 후보 집합"이 가장 크게 남도록 yes/no를 고른다.
따라서 "운 좋게 빨리 맞히기"는 통하지 않는다. 최악의 후보 집합을 매 질의마다 최대로 줄이는 전략(이분/삼분 탐색, 결정 트리 균형화)이 정답이다.
적대적 분석으로 전략 설계
전략의 옳음은 "적이 어떻게 답하든 \(Q\)번 내 확정"을 보이는 것. 보통 잠재 함수(potential) = 남은 후보 수 또는 불확실성. 각 질의가 잠재 함수를 일정 비율 이상 줄이도록 설계한다.
| 질의 응답 | 후보 절감 | 결과 |
|---|---|---|
| 이분(균형) | 항상 \(\ge\) 절반 | \(\log N\) 보장 |
| 불균형 질의 | 적이 큰 쪽 선택 | 느림/실패 |
흔한 패턴
- 이분 탐색형: 숨은 값/경계 찾기.
- 그래프 탐색형: 미지의 그래프를 질의로 복원(차수/연결성 질의).
- 비교 기반: 정렬류, "둘 중 큰 것?" 질의 횟수 최소화.
- 이진 인코딩: 한 질의에 여러 비트 묶어 정보량 극대화.
구현 체크리스트
- 매 출력 후 flush(
endl또는 명시적 flush). 미스 시 TLE/데드락. - 질의 횟수를 카운트하고 상한 직전에 안전하게 종료.
- 판정기의 "끝/오답 신호"(예: -1 응답)를 받으면 즉시 exit.
- 로컬 테스트용 가짜 판정기(특히 적응적 버전)를 만들어 검증.
다음 강의에서 구성 문제와 "증명을 알고리즘으로 바꾸기"를 본다.