백준 문제풀이

[BOJ C++] 백준 2828번: 사과 담기 게임

audxkawjd17 2025. 9. 7. 14:07

 📚 문제

[BOJ C++] 백준 2828번: 사과 담기 게임
https://www.acmicpc.net/problem/2828

 


 📝 입력 및 출력

 


 🔎 문제 풀이

가장 처음에 바구니는 왼쪽 M칸을 차지하고 있다고 했으므로, 바구니는 1번 칸부터 M번 칸까지 커버할 수 있다. 그 후로는 입력값에 따라 바구니의 위치를 이동하면 된다.

1️⃣ 바구니의 오른쪽 끝(초기에는 M번 칸)보다 더 오른쪽에 사과가 떨어지는 경우, 오른쪽 끝이 해당 위치에 닿게 이동해야 이동 거리가 최솟값이 된다.
예를 들어, M=3이고 초기 상태에서 5번 칸에 사과가 떨어진다면, 바구니의 오른쪽 끝을 3→5로 이동하면 되므로, 이동 거리의 최솟값은 2이다.

 

2️⃣ 바구니의 왼쪽 끝(초기에는 1번 칸)보다 더 왼쪽에 사과가 떨어지는 경우, 왼쪽 끝이 해당 위치에 닿게 이동해야 이동 거리가 최솟값이 된다.

예를 들어, M=3이고 위 경우에서 바구니를 이동하여 현재 바구니가 3~5번 칸을 차지하고 있다고 하자. 이 상태에서 1번 칸에 사과가 떨어진다면, 바구니의 왼쪽 끝을 3→1로 이동하면 되므로, 이동 거리의 최솟값은 2이다.

 

3️⃣ 바구니의 양 끝 값 사이에 사과가 떨어지는 경우, 바구니를 이동하지 않아도 사과를 담을 수 있으므로, 이동 거리의 최솟값은 0이다.
예를 들어, 현재 바구니가 1~5번 칸을 차지하고 있고, 사과가 3번 칸에 떨어진다면, 바구니를 움직이지 않아도 자연스럽게 사과가 바구니에 담길 것이므로 이동 거리의 최솟값은 0이다.


위의 세 가지 경우를 나누어 조건문을 작성하고, 각 경우에 맞게 바구니를 이동시킨 후, 이동 거리의 총합을 계산하면 문제를 해결할 수 있다.


 ⌨️ C++ 코드

더보기
#include<bits/stdc++.h>
using namespace std;

int main(void) {
	int n, m, j, total=0;
	cin >> n >> m >> j;
	int left = 1, right = m; // 바구니의 양 끝 값 저장.
	for(int i=0; i < j; i++){
        int pos, move; // 사과의 위치, 이동 거리.
        cin >> pos;
		if(pos >= left && pos <= right) continue; // 현재 위치에서 커버 가능한 경우.
		else if(pos < left) { // 왼쪽으로 이동하는 경우.
			move = left - pos;
			left -= move;
			right -= move;
            total += move;
        }
		else { // 오른쪽으로 이동하는 경우.
			move = pos - right;
			left += move;
			right += move;
            total += move;
        }
	}
    cout << total;
}