https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV14ABYKADACFAYh
점심 시간에 산책을 다니는 사원들은 최근 날씨가 더워져, 사다리 게임을 통하여 누가 아이스크림을 구입할지 결정하기로 한다.
김 대리는 사다리타기에 참여하지 않는 대신 사다리를 그리기로 하였다.
사다리를 다 그리고 보니 김 대리는 어느 사다리를 고르면 X표시에 도착하게 되는지 궁금해졌다. 이를 구해보자.
아래 <그림 1>의 예를 살펴보면, 출발점 x=0 및 x=9인 세로 방향의 두 막대 사이에 임의의 개수의 막대들이 랜덤 간격으로 추가되고(이 예에서는 2개가 추가됨) 이 막대들 사이에 가로 방향의 선들이 또한 랜덤하게 연결된다.
X=0인 출발점에서 출발하는 사례에 대해서 화살표로 표시한 바와 같이, 아래 방향으로 진행하면서 좌우 방향으로 이동 가능한 통로가 나타나면 방향 전환을 하게 된다.
방향 전환 이후엔 다시 아래 방향으로만 이동하게 되며, 바닥에 도착하면 멈추게 된다.
문제의 X표시에 도착하려면 X=4인 출발점에서 출발해야 하므로 답은 4가 된다. 해당 경로는 별도로 표시하였다.
아래 <그림 2>와 같은 100 x 100 크기의 2차원 배열로 주어진 사다리에 대해서, 지정된 도착점에 대응되는 출발점 X를 반환하는 코드를 작성하라 (‘0’으로 채워진 평면상에 사다리는 연속된 ‘1’로 표현된다. 도착 지점은 '2'로 표현된다).
[제약 사항]
한 막대에서 출발한 가로선이 다른 막대를 가로질러서 연속하여 이어지는 경우는 없다.
[입력]
입력 파일의 첫 번째 줄에는 테스트 케이스의 번호가 주어지며, 바로 다음 줄에 테스트 케이스가 주어진다.
총 10개의 테스트 케이스가 주어진다.
[출력]
#부호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 도착하게 되는 출발점의 x좌표를 출력한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Solution {
// 출발지점에서부터 시작점 찾기
// 출발지점에서 위로 계속 올라가기
// 좌, 우 통로 있으면 거기로 가기
// 그러면서 계속 올라가기 !! 이동할 때는 무조건 visited
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[][] map = new int[100][100];
int dest_i = 0; // 목적지 i주소
int dest_j = 0; // 목적지 j주소
int[][] d = { // 이동필터
{ 0, -1 }, // 좌
{ 0, 1 }, // 우
{ -1, 0 } // 상
};
for (int t = 1; t <= 10; t++) {
String asdf = br.readLine(); // 굳이 숫자 하나 넣기
// 배열에 사다리 값 넣기
for (int i = 0; i < 100; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < 100; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
if (map[i][j] == 2) { // 도착지 찾았을 때
dest_i = i;
dest_j = j;
}
}
} ///////////// 사다리 값 넣기 끝 ////////////////////
// 도착지점에서 점점 위로 올라가기
int i = dest_i, j = dest_j;
while (i != 0) { // 최상단에 도달할 때까지
// System.out.println("i: "+ i+" j: "+j);
for (int n = 0; n < 3; n++) { // 좌,우,상 으로 이동
int ni = i + d[n][0];
int nj = j + d[n][1];
if (ni >= 0 && ni < 100 && nj >= 0 && nj < 100) {
if (map[ni][nj] == 1) {// 범위내이며 1일때 이동
i = ni;
j = nj;
map[ni][nj] = -1;
break;
}
}
}
}
//j가 0이므로 출발지에 도달함
System.out.printf("#%d %d\n", t, j);
} // 테스트케이스 끝
}
}
출발지점에서 하나하나 검사해가며 도착지점으로 가기엔 복잡해진다.
도착지점에서 위로 올라가며 출발지점을 찾아야한다.
풀이 순서
옆으로 가는 사다리가 있을 땐 무조건 그쪽으로 가야 하므로 이동필터의 순서를 좌,우,상으로 한다.
맵에 숫자를 입력하며 도착지(2) 검출 시 그곳의 좌표를 따로 저장한다.
도착지점부터 좌, 우, 상을 검사하며 범위 내 and 사다리인지 판별 후 이동한다.
또한 방문처리도 한다.
i가 0이면 최상단. 즉 출발지점에 도달했으므로 반복문에서 탈출하고 j의 값을 출력한다.
나..이젠 리스트 탐색 고수일지도?