손상 여부, 여분 여부를 나타내는 Boolean 배열을 2개 선언한다.
카약을 하나 더 가져왔더라도, 본인 팀의 카약이 손상되면 본인 팀을 수리한다.
이러한 경우에는 카약을 가져오지 않은 팀과 동일하다.
배열의 좌측부터 카약의 손상여부를 확인한다. 만약 카약이 손상되었다면 좌,우의 팀이 여분의 카약이 있는지 확인한다.
좌,우의 팀 모두가 여분 카약을 가져왔다면 좌측 팀의 카약을 사용한다.
좌측부터 손상여부를 확인하고 있기 때문에, 좌측 팀의 여분 카약은 현재 체크 중인 팀 외에는 어차피 사용 할 수 없기 때문이다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BOJ_4_2891{
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(bf.readLine());
int N = Integer.parseInt(st.nextToken());
int S = Integer.parseInt(st.nextToken());
int R = Integer.parseInt(st.nextToken());
boolean[] arr = new boolean[N];
st = new StringTokenizer(bf.readLine());
for (int i = 0; i < S; i++) {
int s = Integer.parseInt(st.nextToken());
arr[s-1]=true;
} // 손상된 팀은 true로 표현
st = new StringTokenizer(bf.readLine());
boolean[] rent = new boolean[N]; // 빌려줄 수 있는지 상태 관리
for (int i = 0; i < R; i++) {
int r = Integer.parseInt(st.nextToken());
rent[r-1]=true;
} // 여분을 가져온 팀은 true
int ans = 0; // 출발 할 수 없는 팀 수
// 자기꺼 먼저 다 수리하기
for(int i=0; i<N; i++) {
if(arr[i]&&rent[i]) {
arr[i]=false;
rent[i]=false;
}
}
// 첫번째 팀이 손상된 경우
if(arr[0]) {
if(rent[1]) rent[1]=false;
else ans++;
}
// 중간 팀이 손상된 경우
for(int i=1; i<N-1; i++) {
if(arr[i]) {
if(rent[i-1]) continue;
else if(rent[i+1]) rent[i+1]=false;
else ans++;
}
}
// 마지막 팀이 손상된 경우
if(arr[N-1]) {
if(rent[N-2]) rent[N-2]=false;
else ans++;
}
System.out.println(ans);
}
}
문제의 테스트 케이스 외에 본인 팀의 카약이 손상되었지만, 여분이 있어서 스스로 수리하는 경우를 생각해야 한다.
처음에는 -1, 0, 1로 각각 팀의 상태를 표현하려 했으나, boolean으로 표현하는 것이 코드 작성이나 생각하기에 더 편했다.