작성일 :

문제 링크

7194번 - Harmoonia

설명

두 성부로 이루어진 악보가 주어질 때, 연속한 두 음 사이에 평행5도가 나타나는 위치를 찾는 문제입니다.


접근법

평행5도는 연속한 두 줄을 비교해서 판정할 수 있습니다.

현재 줄과 이전 줄을 놓고 볼 때, 두 줄 모두에서 두 성부의 음정 차이가 12로 나눈 나머지 7이어야 합니다. 그리고 두 성부의 음높이도 모두 바뀌어 있어야 합니다. 이 조건을 만족하면 이전 줄 번호를 출력하면 됩니다.

입력이 매우 크므로 모든 음을 저장할 필요는 없습니다. 이전 줄의 두 음과 그 줄이 완전5도였는지만 기억하면서 한 번만 순회하면 됩니다.

평행5도가 한 번도 없으면 POLE를 출력합니다.



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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
using System;
using System.IO;
using System.Text;

class FastScanner {
  private readonly Stream _stream = Console.OpenStandardInput();
  private readonly byte[] _buffer = new byte[1 << 16];
  private int _index;
  private int _size;

  private int Read() {
    if (_index >= _size) {
      _size = _stream.Read(_buffer, 0, _buffer.Length);
      _index = 0;
      if (_size == 0)
        return -1;
    }

    return _buffer[_index++];
  }

  public int ReadInt() {
    int c = Read();
    while (c <= 32) {
      c = Read();
    }

    int sign = 1;
    if (c == '-') {
      sign = -1;
      c = Read();
    }

    int value = 0;
    while (c > 32) {
      value = value * 10 + (c - '0');
      c = Read();
    }

    return value * sign;
  }
}

class Program {
  static void Main() {
    var fs = new FastScanner();
    int n = fs.ReadInt();

    if (n == 0) {
      Console.WriteLine("POLE");
      return;
    }

    int prevA = fs.ReadInt();
    int prevB = fs.ReadInt();
    bool prevFifth = ((prevA - prevB) % 12) == 7;

    var sb = new StringBuilder();
    int count = 0;

    for (int i = 2; i <= n; i++) {
      int a = fs.ReadInt();
      int b = fs.ReadInt();
      bool currFifth = ((a - b) % 12) == 7;

      if (prevFifth && currFifth && prevA != a && prevB != b) {
        sb.Append(i - 1).Append('\n');
        count++;
      }

      prevA = a;
      prevB = b;
      prevFifth = currFifth;
    }

    if (count == 0)
      Console.WriteLine("POLE");
    else
      Console.Write(sb.ToString());
  }
}

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
34
35
36
37
38
39
40
41
42
43
44
45
#include <bits/stdc++.h>
using namespace std;

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

  int n;
  cin >> n;

  if (n == 0) {
    cout << "POLE\n";
    return 0;
  }

  int prevA, prevB;
  cin >> prevA >> prevB;
  bool prevFifth = ((prevA - prevB) % 12) == 7;

  vector<int> answer;

  for (int i = 2; i <= n; i++) {
    int a, b;
    cin >> a >> b;
    bool currFifth = ((a - b) % 12) == 7;

    if (prevFifth && currFifth && prevA != a && prevB != b) {
      answer.push_back(i - 1);
    }

    prevA = a;
    prevB = b;
    prevFifth = currFifth;
  }

  if (answer.empty()) {
    cout << "POLE\n";
  } else {
    for (int i = 0; i < (int)answer.size(); i++) {
      cout << answer[i] << "\n";
    }
  }

  return 0;
}

Tags: 7194, BOJ, C#, C++, 구현, 백준, 알고리즘

Categories: ,