문제 링크:
문제:
상근이는 오락실에서 바구니를 옮기는 오래된 게임을 한다. 스크린은 N칸으로 나누어져 있다. 스크린의 아래쪽에는 M칸을 차지하는 바구니가 있다. (M<N) 플레이어는 게임을 하는 중에 바구니를 왼쪽이나 오른쪽으로 이동할 수 있다. 하지만, 바구니는 스크린의 경계를 넘어가면 안 된다. 가장 처음에 바구니는 왼쪽 M칸을 차지하고 있다.
스크린의 위에서 사과 여러 개가 떨어진다. 각 사과는 N칸중 한 칸의 상단에서 떨어지기 시작하며, 스크린의 바닥에 닿을때까지 직선으로 떨어진다. 한 사과가 바닥에 닿는 즉시, 다른 사과가 떨어지기 시작한다.
바구니가 사과가 떨어지는 칸을 차지하고 있다면, 바구니는 그 사과가 바닥에 닿을 때, 사과를 담을 수 있다. 상근이는 사과를 모두 담으려고 한다. 이때, 바구니의 이동 거리의 최솟값을 구하는 프로그램을 작성하시오.
입력:
첫째 줄에 N과 M이 주어진다. (1 ≤ M < N ≤ 10) 둘째 줄에 떨어지는 사과의 개수 J가 주어진다. (1 ≤ J ≤ 20) 다음 J개 줄에는 사과가 떨어지는 위치가 순서대로 주어진다.
출력:
모든 사과를 담기 위해서 바구니가 이동해야 하는 거리의 최솟값을 출력한다.

문제 이해:
처음에 문제만 보고 이해가 안되었다.. 이 문제는 예시를 들어 이해하면 바로 이해할 수 있을 것이다.

- 바구니 시작 위치: 1번 칸
- 첫 번째 과일도 1번 칸에 떨어지므로 이동 없이 수확 성공
이동 횟수: 0
- 첫 번째 과일도 1번 칸에 떨어지므로 이동 없이 수확 성공
- 두 번째 과일: 5번 칸에 떨어짐
- 현재 바구니는 1번 칸에 있음 → 5번 칸까지 가려면 4칸 이동
이동 횟수 누적: 4
- 현재 바구니는 1번 칸에 있음 → 5번 칸까지 가려면 4칸 이동
- 세 번째 과일: 3번 칸에 떨어짐
- 이전에 바구니는 5번에 있음 → 3번으로 이동하려면 2칸 이동
이동 횟수 누적: 4 + 2 = 6
- 이전에 바구니는 5번에 있음 → 3번으로 이동하려면 2칸 이동
문제 구현 방식:
즉 문제를 구현하기 위해서 다음과 같은 조건을 생각하며 구현하면 된다.
1. 바구니를 왼쪽 끝 위치 하나로 표현하고
2. 사과가 떨어질 때마다 바구니 범위를 확인하며
3. 범위 밖이라면 한 칸씩 이동시키고 이동 횟수를 누적하여
4. 모든 사과를 수확할 때까지 반복한다
이를 코드로 구현하면 다음과 같다.
정답 코드:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int[] apple; //어디에 떨어지는지에 대한 사과 배열
static int N,M;
static int result=0;
public static void appleGame(){
int curLocation=1; //현재 위치
//사과를 순차적으로 떨어뜨리는 반복문
for(int i=0;i<apple.length ;i++){
//바구니에 들어갈때까지 이동하면서 반복
while (true){
//현재 위치에서 사과를 담을 수 있다면
if(curLocation+(M-1) >= apple[i] && curLocation <= apple[i]){
break;
}
else {
//사과가 현재 바구니 이전에 있다면 위치 감소
if(curLocation>apple[i]){
curLocation--;
}
//사과가 현재 바구니 이후에 있다면 위치 증가
else{
curLocation++;
}
}
//이동 횟수 증가
result++;
}
}
}
public static void main(String[] args) throws IOException {
int appleCount;//떨어뜨릴 사과 개수
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st=new StringTokenizer(br.readLine());
//N과 M입력
N=Integer.parseInt(st.nextToken());
M=Integer.parseInt(st.nextToken());
//떨어 뜨릴 사과 횟수 입력
appleCount= Integer.parseInt(br.readLine());
//횟수만큼 동적할당
apple = new int[appleCount];
//떨어질 위치 입력
for (int i = 0; i < appleCount; i++) {
apple[i]=Integer.parseInt(br.readLine());
}
//사과 담기 게임 시작
appleGame();
//결과 출력
System.out.println(result);
}
}
감사합니다.
'코딩 테스트' 카테고리의 다른 글
| [백준] 4659 비밀번호 발음하기 (JAVA) (1) | 2025.07.06 |
|---|---|
| [백준] 2910 빈도 정렬 (JAVA) (1) | 2025.07.04 |
| [백준] 1992 쿼드트리 (JAVA) (1) | 2025.07.03 |
| [백준] 2583 영역 구하기 (JAVA) (2) | 2025.07.02 |
| [백준] 2468 안전 영역 (JAVA) (0) | 2025.07.02 |
