알고리즘/백준

[파이썬, 자바] BOJ_2828(사과 담기 게임)

딱따구르리 2021. 1. 22. 17:34
728x90
반응형

문제

 

https://www.acmicpc.net/problem/2828

 

2828번: 사과 담기 게임

상근이는 오락실에서 바구니를 옮기는 오래된 게임을 한다. 스크린은 N칸으로 나누어져 있다. 스크린의 아래쪽에는 M칸을 차지하는 바구니가 있다. (M<n) 플레이어는="" 게임을="" 하는="" 중에="" 바구니를="" <="" p=""> </n)>

www.acmicpc.net


 

해설

 

이 문제는 많이들 해봤을 단순한 게임을 가지고 낸 문제이다.

그치만 글로 읽으니 처음엔 무슨 말인가 잠깐 헷갈렸었다.

이런 게임이다.

처음엔 바구니의 위치를 저장하지 않고 풀었다가 틀렸었다.

 

다시 제대로 푼다면, 

우선 바구니의 크기는 스크린 크기인 n보다만 작으면 되기 때문에 1이라는 보장이 없다.

그래서 바구니의 왼쪽 좌표와 오른쪽 좌표를 움직일 때마다 변경을 해줘야 한다.

 

바구니의 최초 좌표는 무조건 스크린의 가장 왼쪽 m칸을 차지한다고 했으니, 왼쪽 = 1, 오른쪽 = m일 것이다.

그리고 이동 거리를 저장할 변수도 필요하기 때문에 우선 초기화를 해놓고 for문을 돌리면 된다.

 

사과가 떨어지는 경우를 생각해보면 3가지 경우가 있다.

 

1) 바구니 안에 떨어지는 경우

2) 바구니 왼쪽에 가깝게 떨어지는 경우

3) 바구니 오른쪽에 가깝게 떨어지는 경우

 

위의 3가지 경우에 따라 다르게 계산을 해주면 된다.

 

1) 바구니 안에 떨어진다면,

continue로 넘겨주면 된다. 따로 움직이지 않아도 된다.

 

2) 바구니 왼쪽에 가깝게 떨어진다면,

우선 이동 거리를 먼저 계산 한 후

오른쪽 좌표, 왼쪽 좌표 순으로 계산해야 한다.

왼쪽 좌표를 먼저 옮겨버리면 오른쪽 좌표를 계산할 때 왼쪽 좌표를 이용할 수 없다.

왼쪽 좌표를 다른 변수에 넣어놓는다면 먼저 옮겨도 괜찮지만 그러면 쓸데없는 코드 한 줄이 생기게 되므로 하지 않는게 좋다.

 

3) 바구니 오른쪽에 가깝게 떨어진다면,

왼쪽에 가깝게 떨어진 경우와 동일하게 풀면 되는데,

다른 점이 있다면 이 경우엔, 왼쪽 좌표, 오른쪽 좌표 순으로 계산해야 한다는 것이다.

 

마지막으로 이동 거리를 출력하게 되면 끝이다.


코드

 

-파이썬

#백준 2828(사과 담기 게임)
import sys
input = sys.stdin.readline

n, m = map(int, input().split())  #스크린 크기, 바구니가 차지하는 크기
apple = int(input())  #사과 개수

left = 1  #바구니 왼쪽 좌표
right = m  #바구니 오른쪽 좌표
sum = 0  #이동 거리

for _ in range(apple):
    where = int(input())  #사과 위치
    
    if left <= where and where <= right:  #바구니 안에 떨어지면
        continue
        
    if left > where:  #바구니 왼쪽에 가깝게 떨어지면
        sum += (left - where)
        right -= (left - where)
        left = where
    else:  #바구니 오른쪽에 가깝게 떨어지면
        sum += (where - right)
        left += (where - right)
        right = where

print(sum)

 

-자바

//백준 2828(사과 담기 게임)
import java.util.*;
import java.io.*;

public class Boj_2828 {

	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		int n = Integer.parseInt(st.nextToken());  //스크린
		int m = Integer.parseInt(st.nextToken());  //바구니 크기
		int apple = Integer.parseInt(br.readLine());  //사과 개수
		
		int left = 1;  //바구니 왼쪽 좌표
		int right = m;  //바구니 오른쪽 좌표
		int sum = 0;  //이동 거리
		
		for(int i = 0; i < apple; i++) {
			int where = Integer.parseInt(br.readLine());
			
			//바구니 안에 떨어지는 경우
			if(left <= where && where <= right) {
				continue;
			}
			
			//바구니 왼쪽에 가깝게 떨어지는 경우
			if(left > where) {
				sum += (left - where);
				right -= (left - where);
				left = where;
			}
			
			//바구니 오른쪽에 가깝게 떨어지는 경우
			else{
				sum += (where - right);
				left += (where - right);
				right = where;
			}
		}
		
		System.out.println(sum);

	}

}
728x90
반응형