본문으로 건너뛰기
김신건의 로그

케이스 워크 (Case Work)

· 수정 · 📖 약 3분 · 1,073자/단어 #algorithm #foundation #case-work
case work, 케이스 워크, 경우 분류, 조건 분기

정의

케이스 워크 (Case Work) 는 문제를 여러 조건/경우로 분류하여 각각 해결하는 패턴.

if-else, switch-case, 의사결정 트리 등으로 구현. 복잡한 조건을 상호 배타적 케이스로 쪼개 가독성과 정확성 확보.

PS 에서는 “조건 A, B, C 중 어느 쪽?” 판별이 핵심. 누락 케이스 = WA, 중복 케이스 = 불필요 분기.

문제 상황과 동기

복잡한 조건이 얽힌 문제 (예: “N이 짝수면 A, 홀수면 B, 단 N=1은 예외”).

  • naive: 단일 if-else 로 모든 조건 한 번에 처리 → 가독성 폭망, 디버깅 지옥.
  • case work: 조건 분류 명시 → 각 케이스 독립 해결 → 테스트·검증 쉬움.

핵심 통찰: 상호 배타적 조건 (mutually exclusive) + 완전 (exhaustive).

자주 등장하는 PS 위치:

  • 기하 (점/선/면 위치 관계: 교차/접촉/포함/외부)
  • 그래프 (노드 차수: 0, 1, 2, ≥3)
  • 정수론 (소수/합성수/1, 짝수/홀수, mod k 나머지)
  • 시뮬레이션 (4방향 이동, 상태 전이)

시각화

핵심 아이디어

invariant: 모든 입력은 정확히 하나의 케이스에 속함 (no overlap, no gap).

체계화 방법:

  1. 조건 열거: 가능한 모든 경우 나열.
  2. 우선순위 정렬: 예외 케이스를 먼저 (예: N=0, N=1).
  3. 상호 배타성 검증: if A else if B else C (순서 중요).
  4. 완전성 검증: 모든 입력이 하나의 케이스에 들어가는가.
  5. 테스트: 각 케이스마다 입력 1개씩 확인.

알고리즘

case_work(input):
    if exceptional_case_1(input):
        return handle_case_1(input)
    else if exceptional_case_2(input):
        return handle_case_2(input)
    else if common_case_A(input):
        return handle_A(input)
    else if common_case_B(input):
        return handle_B(input)
    else:
        return default_case(input)

구현

예제 1: 삼각형 판별 (3개 변 길이)

a, b, c 로 삼각형 가능 여부 + 종류 (정삼각형, 이등변, 직각, 일반).

조건 분류:

  1. 삼각형 불가능: a + b ≤ c 또는 순열.
  2. 정삼각형: a == b == c.
  3. 이등변: a == b 또는 b == c 또는 c == a.
  4. 직각: a² + b² == c² 또는 순열.
  5. 일반 삼각형.
// 삼각형 케이스 분류, O(1)
#include <bits/stdc++.h>
using namespace std;
int main() {
  int a, b, c; cin >> a >> b >> c;
  // 삼각형 성립 조건
  if (a + b <= c || b + c <= a || c + a <= b) {
      cout << "not a triangle\n";
      return 0;
  }
  // 정삼각형
  if (a == b && b == c) {
      cout << "equilateral\n";
  }
  // 이등변
  else if (a == b || b == c || c == a) {
      cout << "isosceles\n";
  }
  // 직각
  else if (a*a + b*b == c*c || b*b + c*c == a*a || c*c + a*a == b*b) {
      cout << "right\n";
  }
  // 일반
  else {
      cout << "scalene\n";
  }
}
stdin
3 3 3
결과
equilateral

예제 2: 윤년 판별

조건 (그레고리력):

  1. 4로 나누어떨어지면 윤년.
  2. 단, 100으로 나누어떨어지면 평년.
  3. 단, 400으로 나누어떨어지면 윤년.
// 윤년 케이스, O(1)
#include <bits/stdc++.h>
using namespace std;
int main() {
  int y; cin >> y;
  if (y % 400 == 0) {
      cout << "leap\n";
  } else if (y % 100 == 0) {
      cout << "common\n";
  } else if (y % 4 == 0) {
      cout << "leap\n";
  } else {
      cout << "common\n";
  }
}
stdin
2000
결과
leap

예제 3: 사분면 판별

점 (x, y) 가 어느 사분면 / 축 위에 있는가?

조건 분류: x>0 y>0 → 1사분면, x<0 y>0 → 2사분면, x<0 y<0 → 3사분면, x>0 y<0 → 4사분면, x=0 또는 y=0 → 축.

// 사분면 케이스, O(1)
#include <bits/stdc++.h>
using namespace std;
int main() {
  int x, y; cin >> x >> y;
  if (x == 0 || y == 0) {
      cout << "on axis\n";
  } else if (x > 0 && y > 0) {
      cout << "Q1\n";
  } else if (x < 0 && y > 0) {
      cout << "Q2\n";
  } else if (x < 0 && y < 0) {
      cout << "Q3\n";
  } else {
      cout << "Q4\n";
  }
}
stdin
1 1
결과
Q1

복잡도

항목
시간O(1) ~ O(K) (K=케이스 수, 보통 상수)
공간O(1)
구현 난이도낮음 (조건 열거만 정확하면 됨)

변형

기법설명
의사결정 트리조건 순서를 트리로 시각화
lookup 테이블if-else 대신 배열/map 로 케이스 매핑
비트마스크여러 boolean 조건을 정수 하나로 압축 (2^K 케이스)
다항식 판별케이스마다 고유 공식 (예: 사분면 = sign(x) * 2 + sign(y))

함정

1. 케이스 누락 (gap)

“홀수/짝수” 만 처리하고 0 을 잊음. 완전성 체크리스트 작성.

2. 케이스 중복 (overlap)

if x > 0if x >= 0 동시 적용 → 하나의 입력이 두 케이스에 들어감. 상호 배타성 검증.

3. 조건 순서 실수

윤년 예제: y % 4 == 0 를 먼저 체크하면 400, 100 예외 처리 안 됨. 예외 케이스를 먼저.

4. 부동소수점 비교

기하 문제에서 a == b 대신 abs(a - b) < eps 사용.

BOJ 연습 문제

번호제목정답률링크
BOJ 2753윤년-kokoa-lab
BOJ 14681사분면 고르기-kokoa-lab
BOJ 9498시험 성적-kokoa-lab
BOJ 2884알람 시계-kokoa-lab

참고

이 글의 용어 (3개)
시뮬레이션 (Simulation)algorithm
정의 시뮬레이션 (Simulation) 은 문제에서 제시한 규칙을 그대로 코드로 옮겨 한 단계씩 따라가는 알고리즘. 복잡한 로직보다 정확한 구현과 엣지 케이스 처리 가 핵심. P…
애드 혹 (Ad Hoc)algorithm
정의 애드 혹 (Ad Hoc) 은 범용 알고리즘이 아닌, 그 문제만의 관찰·트릭·창의적 사고로 푸는 문제 유형. 라틴어로 "이 목적을 위한" 이라는 뜻. 정형화된 자료구조나 DP…
해 구성하기 (Constructive)algorithm
정의 해 구성하기 (Constructive Algorithm) 는 답의 존재를 증명하는 대신, 명시적으로 답을 만드는 문제 유형. "가능한가?" → YES/NO 가 아니라, "가…

이 개념을 다룬 위키 페이지 (2)

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기