Question
문제 해설
- 크기 NxN인 지도
- 각 칸은 높이가 존재
- 하나의 행 / 열 = 길
- 길을 지나려면 '모든 칸의 높이가 동일' OR '지나갈 수 있도록 경사로 설치'
- 경사로 조건
- 높이는 항상 1, 길이는 L
- 경사로는 낮은 칸과 높은 칸 연결 : 서로 높이의 차가 1이여야 함
- 경사로는 낮은 칸에 설치
- L개의 연속된 칸에 결사로의 바닥이 모두 접해햐 함
- 길의 범위 안에 경사로 설치해야 함
- 지나갈 수 있는 길의 개수 구하시오
Solution
풀이 접근 방법
- 경사로의 높이 = 1
- 현재 칸과 다음 칸의 높이 비교 시 1 초과이면 경사로 설치 불가
- 다른 칸 비교할 필요 없이 이동 자체가 불가능
- 경사로의 길이만큼 바닥에 같은 수가 이어져야 한다 + 경사로는 상대적으로 낮은 칸에 놓임
- 3(현재) > 2 (그 다음): 현재보다 하나 더 앞에 있는 칸부터 앞으로 탐색하면서 경사로 설치 여부 확인
- 앞으로 탐색 = 만약 설치 가능하다면 그 다음 탐색할 칸 앞으로 당겨주기
- 3(현재) > 4 (그 다음): 현재부터 뒤로 탐색하면서 경사로 설치 여부 확인
- 길의 범위 안에 경사로 설치해야 함
- 경사로 길이만큼 반복문 돌리면서 배열의 범위 넘어가지 않게 체크해줘야 함
- 이미 놓은 부분에는 경사로 놓일 수 없음
- EX) 경사로 길이 = 1, 칸의 높이 [3, 2, 1, 2, 3]일 때
- 3 > 2 > 1 까지 경사로 놓고 1에서 2로 갈 때 경사로를 놓으면 갈 수 있지만,
- 이미 이전에 2 > 1로 올 때 1에 경사로가 깔려있어서, 그 다음에 경사로 놓을 수 없음
- => boolean[N] 배열로 해당 칸에 이미 설치한 경사로가 있는지 확인
정답 코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
public class Main {
static int N, L;
static int[][] map;
static int roadCnt;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String[] info = br.readLine().split(" ");
N = Integer.valueOf(info[0]);
L = Integer.valueOf(info[1]);
map = new int[N][N];
roadCnt = 0;
for (int i = 0; i < N; i++) {
map[i] = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
}
solution();
bw.write(roadCnt + "\n");
bw.flush();
bw.close();
}
static void solution() {
for (int i = 0; i < N; i++) {
if (roadSolution(map[i].clone())) {
roadCnt += 1;
}
int[] colRoad = new int[N];
for (int j = 0; j < N; j++) {
colRoad[j] = map[j][i];
}
if (roadSolution(colRoad)) {
roadCnt += 1;
}
}
}
static boolean roadSolution(int[] road) {
boolean[] isInstall = new boolean[N];
for (int i = 0; i < N - 1; i++) {
if (Math.abs(road[i] - road[i + 1]) > 1)
return false;
if (road[i] == road[i + 1])
continue;
if (road[i] + 1 == road[i + 1]) {
for (int j = i; j > i - L; j--) {
if (j < 0 || isInstall[j] || road[i] != road[j])
return false;
isInstall[j] = true;
}
}
if (road[i] - 1 == road[i + 1]) {
for (int j = i + 1; j <= i + L; j++) {
if (j >= N || isInstall[j] || road[j] != road[i + 1])
return false;
isInstall[j] = true;
}
i += L - 1;
}
}
return true;
}
}