Question
문제 해설
- N x N 크기의 경주로에 출발점(0, 0)에서 도착점(N - 1, N - 1)까지 경주로 설치하려 함
- 벽(1)이 아닌 빈칸(0)에만 설치할 수 있음
- 상하좌우 인접한 두 빈칸만 연결하여 설치할 수 있음 : 직선 도로 -> 비용 100 추가
- 설치하려는 경주로의 방향이 바뀌는 경우 코너 생김 -> 비용 500 추가
- 경주로를 건설하는데 최소 비용은?
Solution
풀이 접근 방법
- 인덱스를 사용하여 배열에 접근 후 값 수정 -> ArrayList 사용(인덱스를 가진 선형 리스트)
- 남학생 : 입력받은 수의 배수 번호를 가진 스위치 상태 반대로 전환
- 반복문을 통해서 배수 인덱스를 가진 스위치 접근하여 반대로 바꿈
- 여학생 : 입력받은 수와 같은 번호가 붙은 스위치를 중심으로 좌우가 대칭이면서 가장 많은 스위치를 포함하는 구간을 찾아서, 그 구간에 속한 스위치의 상태를 모두 바꿈
- 일단 먼저 입력받은 스위치의 상태 변환
- 받은 수 기준으로 양 옆으로 한칸씩 늘려가면서 양 옆의 두 값이 동일한지 확인
- 동일하면 상태 바꿈
- 동일하지 않거나, 스위치의 범위를 벗어나면 반복문 탈출
- 스위치의 상태를 1번 스위치에서 시작하여 마지막 스위치까지 한 줄에 20개씩 출력
정답 코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class Main {
static int N;
static ArrayList<Boolean> switchList;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
N = Integer.valueOf(br.readLine());
switchList = new ArrayList<Boolean>();
StringTokenizer st = new StringTokenizer(br.readLine());
switchList.add(0, false);
for (int i = 1; i <= N; i++) {
if (st.nextToken().equals("0"))
switchList.add(false);
else
switchList.add(true);
}
int T = Integer.valueOf(br.readLine());
while (T-- > 0) {
st = new StringTokenizer(br.readLine());
int student = Integer.valueOf(st.nextToken());
int number = Integer.valueOf(st.nextToken());
if (student == 1) {
boyPlay(number);
} else {
girlPlay(number);
}
}
StringBuilder answer = new StringBuilder();
for (int i = 1; i <= N; i++) {
if (switchList.get(i))
answer.append("1 ");
else
answer.append("0 ");
if (i % 20 == 0)
answer.append("\n");
}
bw.write(answer.toString() + "\n");
bw.flush();
bw.close();
}
static void boyPlay(int number) {
for (int i = number; i <= N; i += number) {
switchList.set(i, !switchList.get(i));
}
}
static void girlPlay(int number) {
int right = number + 1;
int left = number - 1;
switchList.set(number, !switchList.get(number));
while (isIn(right, left) && (switchList.get(right) == switchList.get(left))) {
switchList.set(right, !switchList.get(right));
switchList.set(left, !switchList.get(left));
right++;
left--;
}
}
static boolean isIn(int right, int left) {
if (0 < right && right <= N && 0 < left && left <= N) {
return true;
}
return false;
}
}