📖 [예제 4-1] 상하좌우
상하좌우 문제 (교재 110p)
난이도 ●○○ | 풀이 시간 15분 | 시간 제한 1초 | 메모리 제한 128MB
문제
아래와 같은 계획서가 주어졌을 때 여행가 A가 최종적으로 도착할 지점의 좌표를 출력하는 프로그램을 작성하시오.
- L : 왼쪽으로 한 칸 이동
- R : 오른쪽으로 한 칸 이동
- U : 위로 한 칸 이동
- D : 아래로 한 칸 이동
가장 왼쪽 위 좌표는 (1,1) 이며, 시작 좌표는 항상 (1,1)이다.
입출력 조건)
입력 조건 | - 첫째 줄에 공간의 크기를 나타내는 N이 주어진다. (1 ≤ N ≤ 100) - 둘째 줄에 여행가 A가 이동할 계획서 내용이 주어진다. (1 ≤ 이동 횟수 ≤ 100) |
출력 조건 | 첫째 줄에 여행가 A가 최종적으로 도착할 지점의 좌표 (X,Y)를 공백으로 구분하여 출력한다. |
입출력 예시)
입력 예시 | 출력 예시 |
5 R R R U D D |
3 4 |
🔑 풀이
입력받은 LRUD에 따라 이동함. 이때, 좌표계를 벗어나는 이동은 무시함
import java.util.*;
class Solution {
public static void main(String[] args) {
// 입력
Scanner scan = new Scanner(System.in);
int N = Integer.parseInt(scan.nextLine());
int x = 1, y = 1;
String line = scan.nextLine();
String[] arr = line.split(" ");
// L R U D에 따른 이동
for (String move : arr) {
if (move.equals("L")) {
if (y - 1 > 0)
y -= 1;
} else if (move.equals("R")) {
if (y + 1 < N)
y += 1;
} else if (move.equals("U")) {
if (x - 1 > 0)
x -= 1;
} else if (move.equals("D")) {
if (x + 1 < N)
x += 1;
}
}
// 정답 출력
System.out.println(x + " " + y);
}
}
📖 [예제 4-2] 시각
시각 문제 (교재 113p)
난이도 ●○○ | 풀이 시간 15분 | 시간 제한 2초 | 메모리 제한 128MB
문제
정수 N이 입력되면 00시 00분 00초부터 N시 59분 59초까지의 모든 시각 중에서 3이 하나라도 포함되는 경우의 수를 구하는 프로그램을 작성하시오.
입출력 조건)
입력 조건 | - 첫째 줄에 정수 N이 입력진다. (0 ≤ N ≤ 23) |
출력 조건 | 00시 00분 00초부터 N시 59분 59초까지의 모든 시각 중에서 3이 하나라도 포함되는 모든 경우의 수를 출력한다. |
입출력 예시)
입력 예시 | 출력 예시 |
5 | 11475 |
🔑 풀이
- 0시부터 N시 59분 59초까지를 String 형태의 time(HHMMSS)으로 나타낸다
- time이 3을 포함하는 경우들을 count
import java.util.*;
class Solution {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int N = scan.nextInt();
int count = 0;
for (int hour = 0; hour < N + 1; hour++) {
for (int min = 0; min < 60; min++) {
for (int sec = 0; sec < 60; sec++) {
String time = hour + "" + min + "" + sec;
if (time.contains("3"))
count++;
}
}
}
System.out.println(count);
}
}
📖 [예제 4-3] 왕실의 나이트
난이도 ●○○ | 풀이 시간 20분 | 시간 제한 1초 | 메모리 제한 128MB
문제
나이트는 L자 형태로만 이동할 수 있으며, 정원 밖으로는 나갈 수 없다. 나이트는 특정한 위치에서 다음과 같은 2가지 경우로 이동할 수 있다.
- 수평으로 두 칸 이동한 뒤에 수직으로 한 칸 이동하기
- 수직으로 두 칸 이동한 뒤에 수평으로 한 칸 이동하기
8 X 8 좌표 평면상에서 나이트의 위치가 주어졌을 때 나이트가 이동할 수 있는 경우의 수를 출력하는 프로그램을 작성하시오. 이때 왕실의 정원에서 행 위치를 표현할 때는 1부터 8로 표현하며, 열 위치를 표현할 대는 a부터 h로 표현한다.
입출력 조건)
입력 조건 | 첫째 줄에 8 X 8 좌표 평면상에서 현재 나이트가 위치한 곳의 좌표를 나타내는 두 문자로 구성된 문자열이 입력된다. 입력 문자는 a1처럼 열과 행으로 이뤄진다. |
출력 조건 | 첫째 줄에 나이트가 이동할 수 있는 경우의 수를 출력하시오. |
입출력 예시)
입력 예시 | 출력 예시 |
a1 | 2 |
🔑 풀이
- a~h, 1~8을 (0,0)~(7,7) 형태로 변환한다
- 나이트가 이동할 수 있는 모든 경우를 2차원 배열 move로 나타낸다
- 나이트의 현재 좌표에서 move를 모두 적용해 보고 결과가 좌표계를 벗어나지 않는 경우를 count
import java.util.*;
class Solution {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String s = scan.next();
// (0,0) ~ (7,7) 좌표계 형태로 옮긴다
int idx_r = s.charAt(0) - 97;
int idx_c = s.charAt(1) - 49;
int count = 0;
// 나이트가 이동할 수 있는 경우를 move로 나타낸다
int[][] move = { { 2, 1 }, { 2, -1 }, { -2, 1 }, { -2, -1 },
{ 1, 2 }, { -1, 2 }, { 1, -2 }, { -1, -2 } };
// idx_r과 idx_c에 move를 적용한 결과가 좌표계를 벗어나지 않는다면 count++
for (int i = 0; i < move.length; i++) {
if (idx_r + move[i][0] >= 0 && idx_r + move[i][0] < 8
&& idx_c + move[i][1] >= 0 && idx_c + move[i][1] < 8)
count++;
}
System.out.println(count);
}
}
✅ idx_r=s.charAt(0)-'a', idx_c=s.char(1)-'0'-1 로 구해도 됨
📖 [예제 4-4] 게임 개발
게임 개발 문제 (교재 118p)
난이도 ●○○ | 풀이 시간 40분 | 시간 제한 1초 | 메모리 제한 128MB
문제
맵은 N x M 크기의 직사각형이며, 맵의 각 칸은 (A, B)로 나타낼 수 있다.
캐릭터는 상하좌우로 움직일 수 있고, 바다로 되어있는 공간에는 갈 수 없다.
매뉴얼은 아래와 같다.
- 현재 위치에서 현재 방향을 기준으로 왼쪽 방향(반시계 방향으로 90도 회전한 방향)부터 차례대로 갈 곳을 정한다.
- 캐릭터의 바로 왼쪽 방향에 아직 가보지 않은 칸이 존재한다면, 왼쪽 방향을 회전한 다음 왼쪽으로 한 칸을 전진한다. 왼쪽 방향에 가보지 않은 칸이 없다면, 왼쪽 방향으로 회전만 수행하고 1단계로 돌아간다.
- 만약 네 방향 모두 이미 가본 칸이거나 바다로 되어있는 칸의 경우에는, 바라보는 방향을 유지한 채로 한 칸 뒤로 가고 1단계로 돌아간다. 단, 이때 뒤쪽 방향이 바다인 칸이라 뒤로 갈 수 없는 경우에는 움직임을 멈춘다.
캐릭터가 방문한 칸의 출력하는 프로그램을 만드시오.
입출력 조건)
입력 조건 | - 첫째 줄에 맵의 세로 크기 N과 가로크기 M을 공백으로 구분하여 입력한다. (3 ≤ N, M ≤ 50) - 둘째 줄에 게임 캐릭터가 있는 칸의 좌표 (A, B)와 바라보는 방향 d가 각각 서로 공백으로 구분하여 주어진다. 방향 d의 값으로는 다음과 같이 4가지가 존재한다. - 0 : 북쪽 - 1 : 동쪽 - 2 : 남쪽 - 3 : 서쪽 - 셋재 줄부터 맵이 육지인지 바다인지에 대한 정보가 주어진다. N개의 줄에 맵의 상태가 북쪽부터 남쪽 순서대로, 각 줄의 데이터는 서쪽부터 동쪽 순서대로 주어진다. 맵의 외곽은 항상 바다로 되어있다. - 0 : 육지 - 1 : 바다 - 처음에 게임 캐릭터가 위치한 칸의 상태는 항상 육지이다. |
출력 조건 | 첫째 줄에 이동을 마친 후 캐릭터가 방문한 칸의 수를 출력한다. |
입출력 예시)
입력 예시 | 출력 예시 |
4 4 1 1 0 1 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 |
3 |
🔑 풀이
✅ front: 왼쪽 좌표가 가지는 값. 1: 바다, 0: 육지, -1: 가본 곳
✅ check: 왼쪽으로 이동할 수 없는 경우라면 ++, 4가 되면 네 방향 모두 이동할 수 없다는 뜻
✅ back: 현재 방향에서 뒷 방향이 가지는 값
- 왼쪽 방향의 좌표를 구한다.
- 왼쪽으로 갈 수 없는 경우(front: -1이거나 1인 경우) 다시 왼쪽으로 돌아보고 check++
- 왼쪽으로 갈 수 있는 경우(front: 0)는 왼쪽으로 이동하고 count++, check = 0으로 초기화.
- 네 방향 모두 이동할 수 없는 경우(check: 4) back으로 이동한다.
- back이 1인 경우 count 출력
import java.util.*;
class Solution {
public static void main(String[] args) {
// 입력
Scanner scan = new Scanner(System.in);
int N = scan.nextInt();
int M = scan.nextInt();
int x = scan.nextInt();
int y = scan.nextInt();
int d = scan.nextInt();
// dir: 북, 동, 남, 서 로 이동하는 방법
int[][] dir = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } };
int[][] map = new int[N][M];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
map[i][j] = scan.nextInt();
}
}
map[x][y] = -1;
int check = 0;
int count = 1;
while (true) {
int f = -1;// f: 왼쪽 방향
if (d - 1 < 0) {
f = d - 1 + 4;
} else {
f = d - 1;
}
int front = map[x + dir[f][0]][y + dir[f][1]];
// 왼쪽으로 갈 수 없는 경우
if (front == 1 || front == -1) {
check++;
d = f;
} else { // 왼쪽으로 갈 수 있는 경우
x = x + dir[f][0];
y = y + dir[f][1];
map[x][y] = -1;
count++;
check = 0;
}
// 네 방향 모두 이동할 수 없는 경우
if (check == 4) {
int dx = x, dy = y;
if (d + 2 < 4) {
dx += dir[d + 2][0];
dy += dir[d + 2][1];
} else {
dx += dir[d + 2 - 4][0];
dy += dir[d + 2 - 4][1];
}
int back = map[dx][dy];
if (back == 1)
break;
else {
x = dx;
y = dy;
}
check = 0;
}
}
System.out.println(count);
}
}
'알고리즘' 카테고리의 다른 글
[백준] 2979. 트럭 주차 (java) (0) | 2023.06.05 |
---|---|
[백준] 20006. 랭킹전 대기열 (java) (1) | 2023.06.05 |
[이코테] Chapter 03. 그리디 (java) (0) | 2023.05.29 |
[2021 KAKAO BLIND RECRUITMENT] 합승 택시 요금 java (0) | 2023.05.23 |
[2021 KAKAO BLIND RECRUITMENT] 메뉴 리뉴얼.java (0) | 2023.05.23 |