작성일 :

문제 링크

9437번 - 사라진 페이지 찾기

설명

시험지는 총 N쪽으로 구성되며, 이 수는 항상 4의 배수입니다.

한 장의 종이에는 앞면과 뒷면에 각각 두 쪽씩, 총 4쪽이 인쇄됩니다.

예를 들어 N = 12인 경우, 한 장은 다음과 같은 방식으로 구성됩니다:

  • 앞면 (a, b), 뒷면 (c, d)
  • 실제 페이지 조합: 1, 2, 11, 12 / 3, 4, 9, 10 / 5, 6, 7, 8


이때 어떤 이유로 한 페이지만 남고 나머지 종이가 사라졌다면,

그 페이지만으로 같은 종이에 인쇄되어 있었던 나머지 세 페이지를 찾아 출력하는 문제입니다.


n

접근법

  • 전체 페이지 수 N4의 배수이므로, N ÷ 4 장의 종이가 존재합니다.
  • 각 장은 앞면/뒷면 2쪽씩, 총 4쪽으로 구성됩니다.
  • 각 장을 다음과 같이 구성합니다:
    • i번 장: [앞면 왼쪽, 앞면 오른쪽, 뒷면 왼쪽, 뒷면 오른쪽]
  • 전체 페이지 배열을 구성하고, 각 페이지마다 해당 종이의 번호를 부여합니다.
  • 이후 입력으로 주어진 페이지가 속한 종이를 찾아,
    • 그 종이에 포함된 나머지 세 페이지를 오름차순으로 출력합니다.



Code

C#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using System;
using System.Collections.Generic;

class Program {
  static void Main() {
    while (true) {
      var parts = Console.ReadLine().Split();
      int n = int.Parse(parts[0]);
      if (n == 0) break;

      int p = int.Parse(parts[1]);
      var page = new int[n + 1];

      for (int i = 1; i <= n / 2; i += 2) {
        page[i] = page[i + 1] = (i + 1) / 2;
        if (i + n / 2 <= n)
          page[i + n / 2] = page[i + n / 2 + 1] = n / 4 + 1 - (i + 1) / 2;
      }

      var res = new List<int>();
      for (int i = 1; i <= n; i++) {
        if (i == p) continue;
        if (page[i] == page[p]) res.Add(i);
      }

      res.Sort();
      Console.WriteLine(string.Join(" ", res));
    }
  }
}

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <bits/stdc++.h>

using namespace std;
typedef vector<int> vi;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  while (true) {
    int n; cin >> n;
    if (!n) break;

    vi page(n + 1);
    for (int i = 1; i <= n / 2; i += 2) {
      page[i] = page[i + 1] = (i + 1) / 2;
      if (i + n / 2 <= n)
        page[i + n / 2] = page[i + n / 2 + 1] = n / 4 + 1 - (i + 1) / 2;
    }

    int p; cin >> p;
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
      if (i == p) continue;
      if (page[i] == page[p]) {
        cout << i << (++cnt == 3 ? "\n" : " ");
        if (cnt == 3) break;
      }
    }
  }

  return 0;
}