본문 바로가기
Develop/백준 (Cpp)

[백준] 15787번 : 기차가 어둠을 헤치고 은하수를 (C++)

by Tarra 2023. 8. 25.

15787번 : 기차가 어둠을 헤치고 은하수를


문제)

N개의 기차가 어둠을 헤치고 은하수를 건너려고 한다.

기차는 20개의 일렬로 된 좌석이 있고, 한 개의 좌석에는 한 명의 사람이 탈 수 있다. 

기차의 번호를 1번부터 N번으로 매길 때, 어떠한 기차에 대하여 M개의 명령이 주어진다.

명령의 종류는 4가지로 다음과 같다.

  • 1 i x : i번째 기차에(1 ≤ i ≤ N) x번째 좌석에(1 ≤ x ≤ 20) 사람을 태워라. 이미 사람이 타있다면 , 아무런 행동을 하지 않는다.
  • 2 i x : i번째 기차에 x번째 좌석에 앉은 사람은 하차한다. 만약 아무도 그자리에 앉아있지 않았다면, 아무런 행동을 하지 않는다.
  • 3 i : i번째 기차에 앉아있는 승객들이 모두 한칸씩 뒤로간다. k번째 앉은 사람은 k+1번째로 이동하여 앉는다. 만약 20번째 자리에 사람이 앉아있었다면 그 사람은 이 명령 후에 하차한다.
  • 4 i : i번째 기차에 앉아있는 승객들이 모두 한칸씩 앞으로간다. k번째 앉은 사람은 k-1 번째 자리로 이동하여 앉는다. 만약 1번째 자리에 사람이 앉아있었다면 그 사람은 이 명령 후에 하차한다.

M번의 명령 후에 1번째 기차부터 순서대로 한 기차씩 은하수를 건너는데 조건이 있다.

기차는 순서대로 지나가며 기차가 지나갈 때 승객이 앉은 상태를 목록에 기록하며 이미 목록에 존재하는 기록이라면 해당 기차는 은하수를 건널 수 없다.

예를 들면, 다음 그림을 예로 들었을 때, 1번째 기차와 같이 승객이 앉은 상태는 기록되지 않았기 때문에 은하수를 건널 수있다. 2번째 기차와 같은 상태도 기록되지 않았기 때문에 2번째 기차도 은하수를 건널 수 있다. 3번째 기차는 1번째 기차와 승객이 앉은 상태가 같으므로 은하수를 건널 수 없다.

 

 

처음에 주어지는 기차에는 아무도 사람이 타지 않는다.

은하수를 건널 수 있는 기차의 수를 출력하시오.

 

 

입력 :

입력의 첫째 줄에 기차의 수 N(1 ≤ N ≤ 100000)과 명령의 수 M(1 ≤ M ≤ 100000)가 주어진다. 이후 두 번째 줄부터 M+1번째 줄까지 각 줄에 명령이 주어진다. 

 

 

 

출력 :

은하수를 건널 수 있는 기차의 수를 출력하시오.

 

 

 

 

 

 

풀이)

 

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
#include <iostream>
#include <bitset>
#include <vector>
#include <set>
 
using namespace std;
 
int n, m;
vector<bitset<20>> vec;
set<int> numbers;
 
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
 
    cin >> n >> m;
 
    vec.resize(n + 1, bitset<20>());
    
    int a, i, x;
    for (int _ = 0; _ < m; _++)
    {
        cin >> a;
        
        if (a == 1)
        {
            cin >> i >> x;
            // i번째 자리에 사람이 타있지 않다면 태운다.
            if (!vec[i].test(x - 1)) vec[i].flip(x - 1);
        }
        else if (a == 2)
        {    // 사람이 앉아있다면 하차시킨다.
            cin >> i >> x;
            if (vec[i].test(x - 1)) vec[i].flip(x - 1);
        }
        // bitset은 맨 오른쪽부터 숫자가 채워지므로
        // a == 3, a == 4 일때 방향을 반대로 해야한다.
        else if (a == 3)
        {    // i번째 기차에 앉아 있는 승객들을 뒤로 한칸씩 민다.
            cin >> i;
            vec[i] = (vec[i] << 1);
        }
        else if (a == 4)
        {    // i번째 기차에 앉아 있는 승객들을 앞으로 한칸씩 민다.
            cin >> i;
            vec[i] = (vec[i] >> 1);
        }
    }
    
    for (int i = 1; i < n + 1; i++)
    {
        numbers.insert(vec[i].to_ullong());
    }
 
    cout << numbers.size();
 
    return 0;
}
 
cs

출처 : https://www.acmicpc.net/problem/15787 

 

15787번: 기차가 어둠을 헤치고 은하수를

입력의 첫째 줄에 기차의 수 N(1 ≤ N ≤ 100000)과 명령의 수 M(1 ≤ M ≤ 100000)가 주어진다. 이후 두 번째 줄부터 M+1번째 줄까지 각 줄에 명령이 주어진다. 

www.acmicpc.net