[코드트리] 보도블럭
2025. 4. 2. 17:45ㆍ코테공부/문제풀이
문제
오르막과 내리막을 올라가거나 내려갈 수 있게 경사로를 설치하는데, 아래 사진에 나와있는 예외를 제외하고 한줄을 오갈 수 있으면 면 성공
풀이 방법
- 풀이 시간 : 2시간
- 접근 방식 : 브루트포스
일단 케이스는 4가지 였다.
- 높이 차이가 2 이상인 경우: 경사로 설치 불가
- 오르막길: 다음 값이 1 더 큼
- 내리막길: 다음 값이 1 더 작음
- 평평한 길: 현재 값과 다음 값이 같음
초기 접근(실패)
- Stack을 사용해서 같은 값이 들어올 때까지 쌓는 방식으로 접근
- 평평한 길, 오르막길, 높이차 2 이상인 경우는 비교적 처리 가능했음
- 하지만 내리막길의 경우,
- 이미 설치된 경사로 위에는 또 경사로를 설치할 수 없다는 제약 때문에
- Stack 방식으로는 로직이 지나치게 복잡해짐
예시
더보기
경사로 길이 L = 2
길: [2, 1, 1, 2, 1, 1]
- [2, 1, 1]은 내리막길이 잘 설치되어 통과 가능하지만,
- [1, 1, 2]는 오르막길 설치 시 앞의 경사로 위치와 겹치기 때문에 불가능
최종 해결 방법
- Stack을 버리고, 단순히 현재 위치와 다음 위치의 값을 비교하며 진행
- 오르막이거나 내리막일 경우, 경사로 길이만큼 앞 또는 뒤를 추가로 확인
- 확인 과정에서 다음 조건 체크:
- 경계 벗어남
- 경사로 설치 여부 (visited)
- 높이 불일치
- 위 조건 중 하나라도 충족하지 않으면 불가능한 길로 처리
코드
import java.util.*;
import java.io.*;
public class Main {
static int[][] map;
static int N, L;
static int count;
static boolean[] visited;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
L = Integer.parseInt(st.nextToken());
count = 0;
map = new int[N][N];
for(int i = 0; i < N; i++){
st = new StringTokenizer(br.readLine());
for(int j = 0; j < N; j++){
map[i][j] = Integer.parseInt(st.nextToken());
}
}
for(int i = 0; i < N; i++){
findLine(map[i]);
}
for(int j = 0; j < N; j++){
int[] col = new int[N];
for(int i = 0; i < N; i++){
col[i] = map[i][j];
}
findLine(col);
}
System.out.println(count);
}
private static void findLine(int[] map){
visited = new boolean[N];
boolean flag = true;
for(int i = 0; i < N-1; i++){
int cur = map[i];
int next = map[i+1];
//1 커지는 경우(오르막)
if(cur + 1 == next){
for(int j = 0; j < L; j++){
int index = i-j;
if(index < 0 || visited[index] || map[index] != cur){
flag = false;
break;
}
visited[index] = true;
}
}else if (cur - 1 == next){ //1 작아지는 경우 내리막
for(int j = 1; j <= L; j++){
int index = i+j;
if(index >= N || visited[index] || map[index] != next){
flag = false;
break;
}
visited[index] = true;
}
i += L - 1;
}else if(Math.abs(cur - next) >= 2){ //2이상 차이나는 경우
flag = false;
}
}
if(flag){
count++;
}
}
}
'코테공부 > 문제풀이' 카테고리의 다른 글
[백준] 실버3 두 수의 합 JAVA (0) | 2025.03.27 |
---|