2024. 1. 18. 17:32ㆍ알고리즘
문제
여행가 A는 N X N 크기의 정사각형 공간 위에 서 있다. 이 공간은 1 x 1 크기의 정사각형으로 나누어져 있다. 가장 왼쪽 위 좌표는 (1, 1)이며, 가장 오른쪽 아래 좌표는 (N, N)에 해당한다. 여행가 A는 상, 하, 좌, 우 방향으로 이동할 수 있으며, 시작 좌표는 항상 (1, 1)이다. 우리 앞에는 여행가 A가 이동할 계획이 적힌 계획서가 놓여 있다. 계획서에는 하나의 줄에 띄어쓰기를 기준으로 하여 L, R, U, D 중 하나의 문자가 반복적으로 적혀있다. 각 문자의 의미는 다음과 같다.
- L : 왼쪽으로 한 칸 이동
- R: 오른쪽으로 한 칸 이동
- U: 위로 한 칸 이동
- D: 아래로 한 칸 이동
이때 여행가 A가 N x N 크기의 정사각형 공간을 벗어나는 움직임은 무시된다. 예를 들어, (1, 1)의 위치에서 L 혹은 U를 만나면 무시된다. 계획서가 주어졌을 때 여행가 A가 최종적으로 도착할 지점의 좌표를 출력하는 프로그램을 작성하시오.
- 입력 조건
- 첫째 줄에 공간의 크기를 나타내는 N이 주어진다. (1 <= N <= 100)
- 둘째 줄에 여행가 A가 이동할 계획서 내용이 주어진다. (1 <= 이동 횟수 <= 100)
- 출력 조건
- 첫째 줄에 여행가 A가 최종적으로 도착할 지점의 좌표 (X, Y)를 공백으로 구분하여 출력한다.
즉, 이 문제는 범위 N을 벗어나지 않고, x += 1, x -= 1, y += 1, y -= 1을 수행하여 최종적으로 도착하는 (x, y) 좌표를 구하는 것이다.
1. 내가 작성한 코드
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int max = scanner.nextInt();
int x = 1;
int y = 1;
for(int i=0; i<6; i++){
char c = scanner.next().charAt(0);
if( c == 'R'){
if( y < max ){
y += 1;
}
}
else if( c == 'L'){
if( y > 1 ){
y -= 1;
}
}
else if(c == 'U'){
if( x > 1 ){
x -= 1;
}
}
else if(c == 'D') {
if( x < max ){
x += 1;
}
}
}
System.out.print( x + " " + y );
}
}
나는 배열을 선언하지 않고 문제를 풀어나갔다.
연속적으로 6번동안 L, R, U, D를 입력받는다.
만약 R인 경우 max 값보다 작다면 y += 1을 해주고,
L인 경우 1보다 크다면 y -= 1을 해주고,
U인 경우 1보다 크다면 x -= 1을 해주고,
D인 경우 max 값보다 작다면 x += 1을 해주었다.
2. 동빈님이 작성한 코드
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
// N을 입력받기
int n = sc.nextInt();
sc.nextLine(); // 버퍼 비우기
String[] plans = sc.nextLine().split(" ");
int x = 1, y = 1;
// L, R, U, D에 따른 이동 방향
int[] dx = {0, 0, -1, 1};
int[] dy = {-1, 1, 0, 0};
char[] moveTypes = {'L', 'R', 'U', 'D'};
// 이동 계획을 하나씩 확인
for(int i = 0; i < plans.length; i++){
char plan = plans[i].charAt(0);
// 이동 후 좌표 구하기
int nx = -1, ny = -1;
for(int j = 0; j < 4; j++){
if(plan == moveTypes[j]){
nx = x + dx[j];
ny = y + dy[j];
}
}
// 공간을 벗어나는 경우 무시
if(nx < 1 || ny < 1 || nx > n || ny > n) continue; // 이동 수행
x = nx;
y = ny;
}
System.out.println(x + " " + y);
}
}
동빈님은 값의 변동을 줄 x 배열과 y 배열을 만들었다.
여기서 dx와 dy를 짝지으면, L, R, U, D가 들어왔을 때 더해줄 값이 된다.
예를 들어, L인 경우 x 값은 그대로이고, y 값은 -1을 해주어야 한다.
for문으로 사용자가 입력한 계획(R R R U D D 같은 것)동안 char plan에 plans[i].charAt(0)을 넣어준다.
이때 plans[i] 값은 입력받은 R R R U D D의 공백을 제거한 R, R, R, U, D, D이고,
비교를 위해 char형으로 변동시키기 위해서는 charAt(0)을 해주어야 한다.
int nx = -1, ny = -1로 초기화해주고,
L, R, U, D 배열 moveTypes를 순회하며 만약 같은 값이 있다면 해당 번째의 x 값과 y 값을 더해준다.
예를 들어, 사용자가 입력한 값이 R이라면 moveTypes 배열에 있는 'R'의 인덱스는 1이기 때문에,
dx[1]에 해당하는 0, dy[1]에 해당하는 -1로 변동을 준다.
동빈님과 나의 차이는 배열의 유무와 if문의 횟수 차이이다.
동빈님은 for문을 통해 moveTypes를 순회하며 조건문을 수행해주고,
나는 순회 없이 4개의 조건문을 통해 수행해준다.
또한 공간에서 벗어나는 경우를 한꺼번에 체크해주었다는 점이 다르다.
나는 이중조건문으로 값이 L, R, U, D인지, 값이 max 값보다 큰 지를 체크해주어야 하는데,
동빈님의 코드에서는 L, R, U, D를 한꺼번에 확인하고, max 값보다 큰 지, 1보다 작은 지와 같은 조건도 한꺼번에 수행한다.
'알고리즘' 카테고리의 다른 글
[이코테 with Java] 왕실의 나이트(구현) (0) | 2024.01.19 |
---|---|
[이코테 with Java] 시각(구현) (1) | 2024.01.19 |
[이코테 with Java] 숫자 카드 게임(그리디 알고리즘) (0) | 2024.01.18 |
[이코테 with Java] 큰수의 법칙(그리디 알고리즘) (0) | 2024.01.18 |
[이코테 with Java] 거스름돈 문제 (그리디 알고리즘) (0) | 2024.01.18 |