https://www.acmicpc.net/problem/15787
이차원 배열로 각 기차별로 좌석 정보를 저장하고
승객을 뒤로 한 칸 이동할 때는 인덱스를 역순으로 정렬하고
승객을 앞으로 한 칸 이동할 때는 인덱스를 원래 순으로 정렬한다.
그리고 기차의 탑승 정보를 문자열로 합쳐서
HashSet에 넣은 뒤에 HashSize가 은하수를 건널 수 있는 기차의 수가 된다.
HashSet의 특징과 사용방법에 대해서 배웠습니다.
HashSet에 데이터를 추가해서 add()를 할 때 이미 저장된 같은 데이터가 있는지
확인하고 없으면 추가하지 않는다. 그래서 HashSet에는 항상 다른 데이터만 존재하고
중복이 되지 않는다. 이 점을 이용해서 중복이 필요하지 않은 자료구조가 필요할 때 사용된다.
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
// 입력받기
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken()); // 기차의 수
int m = Integer.parseInt(st.nextToken()); // 명령의 수
int[][] train = new int[n][20]; // 각 기차의 상태
// 입력 - 명령어 처리
for(int i=0;i<m;i++){
st = new StringTokenizer(br.readLine());
int cmdType = Integer.parseInt(st.nextToken()); // 명령어 타입
int trainNum = Integer.parseInt(st.nextToken()) - 1; // 기차 번호
if(cmdType==1 | cmdType==2){
int seatNum = Integer.parseInt(st.nextToken()) - 1; // 좌석 번호
// 1 i x: i번 기차의 x번 좌석에 사람을 태운다.
if(cmdType==1){
train[trainNum][seatNum] = 1;
}
// 2 i x: i번 기차의 x번 좌석에 사람을 하차시킨다.
else if(cmdType==2){
train[trainNum][seatNum] = 0;
}
}
else if(cmdType==3 | cmdType==4){
// 3 i: i번 기차의 좌석을 모두 한 칸씩 뒤로 옮긴다.
if(cmdType==3){
for(int j=19;j>0;j--){
train[trainNum][j] = train[trainNum][j-1];
train[trainNum][j-1] = 0;
}
}
// 4 i: i번 기차의 좌석을 모두 한 칸씩 앞으로 옮긴다.
else if(cmdType==4){
for(int j=0;j<19;j++){
train[trainNum][j] = train[trainNum][j+1];
train[trainNum][j+1] = 0;
}
}
}
else{
System.out.println("Error: cmdType is not 1, 2, 3, 4");
}
}
// 명령 후 중복된 기차 상태 제거
HashSet<String> setTrain = new HashSet<>();
for(int i=0;i<n;i++){
// 기차 상태를 문자열로 변환
String str = "";
for(int j=0;j<20;j++){
str += train[i][j];
}
setTrain.add(str);
}
// 결과 출력
System.out.println(setTrain.size());
}
}