내가 푼 코드)
Scanner sc = new Scanner(System.in);
// 맵크기 n * m
int n = sc.nextInt();
int m = sc.nextInt();
int[][] mapInfo = new int[n][m]; // 맵정보
char[][] check = new char[n][m]; // 기본칸인지 아닌지 판단
// 처음의 캐릭터 위치 (a,b)
int a = sc.nextInt(); //북쪽으로부터 떨어진 칸의 개수
int b = sc.nextInt(); //서쪽으로부터 떨어진 칸의 개수
// 바라보는 방향(d)
int d = sc.nextInt();
// 맵의 정보 입력 (육지 : 0 , 바다 : 1)
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
mapInfo[i][j] = sc.nextInt();
check[i][j] = 'X';
}
}
// 4가지 이동뱡향(동,서,남,북)
int[] x = {0,0,1,-1};
int[] y = {1,-1,0,0};
int result = 1; // 캐릭터가 방문한 칸의 수 (처음에 위치한 칸을 +1 더해줌)
check[a][b] = 'O'; // 초기 좌표는 방문 처리 해줌
while(true) {
int dCount = 0; // 방향 카운트(4방향이 가본칸이거나 바다일경우 4가 됨)
for(int i=0;i<4;i++) {
int next_a = a + x[i];
int next_b = b + y[i];
// 정해진 맵의 크기를 벗어나는지 확인 여부 (이 코드가 없으면 ArrayIndexOutOfBoundsException 발생)
if(next_a < 0 && next_a >= n && next_b < 0 && next_b >= m) {
dCount++;
continue;
}
// 동서남북으로 차례대로 이동했을때 바다가 아니거나 가본곳이 아니라면 캐릭터의 위치를 이동시킴
// 가본칸인지 아닌지 어떻게 판단할수 있는가??? (가본곳인경우 : 'O' , 아닐경우 : 'X')
if(mapInfo[next_a][next_b] == 0 && check[next_a][next_b] == 'X') {
//해당칸을 가본곳임을 표시하고('O') 캐릭터 위치 변경
check[next_a][next_b] = 'O';
a = next_a;
b = next_b;
result++; // 방문한 칸의 수 1증가
break;
}
dCount++;
}
// 4가지 방향 모두 가본칸이거나 바다인 경우
if(dCount == 4) {
// 바라보는 방향을 유지하고 뒤로 한칸이동
if(d == 0) a++; // 북쪽일경우
if(d == 1) b--; // 동쪽일경우
if(d == 2) a--; // 남쪽일경우
if(d == 3) b++; // 서쪽일경우
// 뒤로 한칸 이동했을때 바다칸이라면 움직임(프로그램)을 종료
if(mapInfo[a][b] == 1) break;
}
}
System.out.println(result);
다른 코드)
public class Test2 {
public static int d; // 캐릭터가 바라보는 방향
// 왼쪽으로 회전 ( 북:0 , 동:1 , 남:2 , 서:3) **
public static void turn_left() {
d--;
if(d == -1) d = 3; //북쪽에서 왼쪽으로 회전시 -1인데 서쪽이므로 3이됨
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
// 맵크기 n * m 입력받기
int n = sc.nextInt();
int m = sc.nextInt();
// 초기의 캐릭터 위치(a,b)와 방향(d) 입력받기
int a = sc.nextInt(); //북쪽으로부터 떨어진 칸의 개수
int b = sc.nextInt(); //서쪽으로부터 떨어진 칸의 개수
d = sc.nextInt();
int[][] mapInfo = new int[n][m]; // 맵정보
int[][] check = new int[n][m]; // 방문여부(방문한 칸 : 1 , 방문하지 않은 칸 : 0)
check[a][b] = 1; // 초기 좌표는 방문 처리 해줌
// 4가지 이동뱡향(북,동,남,서)
int[] x = {-1,0,1,0};
int[] y = {0,1,0,-1};
// 맵의 정보 입력 (육지 : 0 , 바다 : 1)
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
mapInfo[i][j] = sc.nextInt();
}
}
// 메뉴얼 대로 이동시작
int result = 1; // 캐릭터가 방문한 칸의 수 (처음에 위치한 칸을 +1 더해줌)
int dCount = 0; // 방향 카운트
while(true) {
turn_left(); // 왼쪽으로 회전(90도 반시계방향)
// 왼쪽으로 회전해서 1칸 움직일 값
int x1 = a + x[d];
int y1 = b + y[d];
// 왼쪽으로 회전이후 정면에 바다가 아니고 가보지 않은 칸일 경우 이동
if(mapInfo[x1][y1] == 0 && check[x1][y1] == 0) {
//해당칸을 가본곳임을 표시하고 캐릭터 위치 변경
check[x1][y1] = 1;
a = x1;
b = y1;
result++; // 방문한 칸의 수 1증가
dCount = 0; // 방향 카운트 초기화
continue;
}
// 바다이거나 가봤던 칸일 경우
dCount++; // 방향 카운트 1증가
// 네 방향 모두 갈 수 없는 경우 **
if(dCount == 4) {
// 바라보는 방향(d)에서 뒤로 한칸이동 (바라보는 방향을 반대로 전환)
// 4가지 이동방향에 있는 인덱스값을 역으로 전환시킴
x1 = a - x[d];
y1 = b - x[d];
// 뒤로 한칸 이동했을때 육지인경우
if(mapInfo[x1][y1] == 0) {
a = x1;
b = y1;
}else { // 바다인경우 프로그램 종료
break;
}
dCount = 0; // 방향 카운트 초기화
}
}
System.out.println(result);
}
}
- 접근 방법은 맞았는데 문제이해를 잘못함
- 코드를 어렵게 짯음... 더 간단하게 코드를 짤수 있도록 문제를 많이 풀어보자
- 코드가 길고 반복적이라면 가급적 메서드로 빼서 분리시키자
'알고리즘&자료구조' 카테고리의 다른 글
BFS,DFS (0) | 2021.01.27 |
---|---|
재귀함수 - 팩토리얼 (0) | 2021.01.26 |
이코테 - 왕실의 나이트 (0) | 2021.01.24 |
이코테 - 상하좌우(구현) (0) | 2021.01.23 |
이코테 - 숫자카드게임 (0) | 2021.01.19 |