N개의 기차가 어둠을 헤치고 은하수를 건너려고 한다.
기차는 20개의 일렬로 된 좌석이 있고, 한 개의 좌석에는 한 명의 사람이 탈 수 있다.
기차의 번호를 1번부터 N번으로 매길 때, 어떠한 기차에 대하여 M개의 명령이 주어진다.
명령의 종류는 4가지로 다음과 같다.
M번의 명령 후에 1번째 기차부터 순서대로 한 기차씩 은하수를 건너는데 조건이 있다.
기차는 순서대로 지나가며 기차가 지나갈 때 승객이 앉은 상태를 목록에 기록하며 이미 목록에 존재하는 기록이라면 해당 기차는 은하수를 건널 수 없다.
예를 들면, 다음 그림을 예로 들었을 때, 1번째 기차와 같이 승객이 앉은 상태는 기록되지 않았기 때문에 은하수를 건널 수있다. 2번째 기차와 같은 상태도 기록되지 않았기 때문에 2번째 기차도 은하수를 건널 수 있다. 3번째 기차는 1번째 기차와 승객이 앉은 상태가 같으므로 은하수를 건널 수 없다.
처음에 주어지는 기차에는 아무도 사람이 타지 않는다.
은하수를 건널 수 있는 기차의 수를 출력하시오.
입력의 첫째 줄에 기차의 수 N(1 ≤ N ≤ 100000)과 명령의 수 M(1 ≤ M ≤ 100000)가 주어진다. 이후 두 번째 줄부터 M+1번째 줄까지 각 줄에 명령이 주어진다.
은하수를 건널 수 있는 기차의 수를 출력하시오.
비트마스킹으로 좌석을 구분하여 풀 수 있다
1번 명령의 경우 1을 해당 좌석번호 까지 쉬프트 시키고 OR연산을 하면 된다
2번 명령의 경우 1을 해당 좌석 번호까지 쉬프트 시키고 NOT 연산 후 AND 연산을 하면 해당 자리를 비울 수 있다
3번 명령의 경우 저장된 수를 왼쪽으로 1번 쉬프트 하면 된다
이때 20번 좌석을 미리 0으로 만들어 둔다
4번 명령의 경우 저장된 수를 오른쪽으로 1번 쉬프트 하면 된다
이때 1번 좌석을 미리 0으로 만들어 둔다
#include <iostream>
#include <algorithm>
using namespace std;
int train[100001];
int main(){
int N, M, ans = 1;
int order, trainNum, index;
cin >> N >> M;
for (int i = 0; i < M; i++){
cin >> order >> trainNum;
if(order< 3) {
cin >> index;
int _idx = 1;
for(int j = 1; j < index; j++) _idx <<= 1;
if (order == 1) train[trainNum] |= _idx;
else train[trainNum] &= ~(_idx);
}
else if(order == 3) {
train[trainNum] &= ~(1 << 19);
train[trainNum] <<= 1;
}
else if(order == 4) {
train[trainNum] &= ~(1);
train[trainNum] >>= 1;
}
}
sort(train + 1, train + 1 + N);
int tmp = train[1];
for(int i = 2; i <= N; i++){
if(tmp != train[i]) ans++;
tmp = train[i];
}
cout << ans;
}