자료구조&알고리즘/백준

[JAVA] 2828번 - 사과담기

celinayk 2024. 8. 16. 23:19
반응형

문제 탐색하기

- 문제에서 구해야 하는 최종 정답은 무엇인지 탐색한 과정
- 그 정답을 구하기 위해 어떻게 코드를 구현해야 할지 고민한 과정
- 문제에 들어오는 범위를 파악하여 어떤 알고리즘을 쓸 수 있을지 고민해 가는 과정

 

문제에서 구해야하는 정답은 이동거리이다

이동거리는 카운트를 하는걸로 구하면 된다

그리고 사과와 바구니는 경우의수가 3가지로 ㄴ분류된다

1. 바구니의 위치와 사과의 위치가 동일할때

2. 사과의 위치보다 바구니가 오른쪽에 있을 때

3. 사과의 위치보다 바구니가 왼쪽에 있을 때

이렇게 나눠서 구한다.

 

핵심은 바구니의 크기가 1이 아닐수도 있다는것이다. 그래서 스크린의 범위를 넘어가지 않게해야한다

그래서 바구니의 왼쪽끝을 지정하는 변수는 최초에는 맨왼쪽에 있으니까 1

바구니의 오른쪽을 지정하는 변수는 m으로 초기화한다

 

이동한 거리는 : 양쪽 위치에서 사과가 떨어지는 위치와 빼기

바구니의 위치는 : 가까운 사과의 위치만큼 조정

코드 설계하기

위의 문제 탐색하기에서 고민한 과정을 토대로 문제 풀이에 대한 실마리를 잡았다면, 문제 풀이를 본격적으로 하기전, 문제를 풀이 위한 로드맵을 그려본다
어떤 순서로 코드를 작성해야 할지, 어떤 함수들을 작성해야 할지 등을 작성

 

1.각 변수들을 입력받는다

2. 사과가 떨어지는 위치를 배열에 숫자로 담는다

3. 배열을 돌면서 각 경우의수로 나눠서 사과와 바구니의 위치에 따라 처리한다

 

시도 회차 수정 사항

- 무분별하게 "맞았습니다" 가 나올때까지 수정하는 형태의 문제 풀이를 반복하면, 내가 어떤 실수를 해서 해당 문제를 틀렸는지 모르게 된다
- 틀렸습니다를 받았다면 왜 틀렸는지 고민핸보고, 어떻게 수정할 수 있는지 고민하는 과정을 작성
- 위에 내가 세울 설계에서 어떤 부분이 틀렸는지도 함께 점검

 

첫번째 시도

=> 사과 바구니 위치 헷갈림

for(int i=0; i<arr.length; i++) {
			if(arr[i]<k) {
				cnt+=arr[i]-k;
				k=arr[i];
			}
			else if(arr[i]>k){
				cnt+=k-arr[i];
				k=arr[i];
			}
		}

 

두번쨰 시도 

=> 정답은 가능, 하지만 바구니의 크기가 1일때만 쓸 수 있는 코드이다. 왜냐하면 바구니의 크기가 2,3,,,이 될 수도 있는데 이부분을 고려하지 못했따

for(int i=0; i<arr.length; i++) {
			if(left<arr[i]) { //내려오는 사과가 바구니보다 오른쪽에 있으면
				cnt+=arr[i]-left;
				left=arr[i];
			}
			else if(arr[i]<left){ //사과가 바구니보다 왼쪽에 있음
				cnt+=left-arr[i];
				left=arr[i];
			}
		}

 

정답코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

public class Main {
	static int arr[][] = new int[5][5];  
	static int ans = 0;
	public static void main(String[] args) throws Exception, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));	
		
		String a[] = br.readLine().split(" ");
		int n =Integer.parseInt(a[0]);
		int m =Integer.parseInt(a[1]);

		int j = Integer.parseInt(br.readLine());
		int arr[] = new int[j];
		
		//사과가 떨어지는 위치를 배열에 숫자로 담음
		for(int i=0; i<arr.length; i++) {
			arr[i] = Integer.parseInt(br.readLine());
		}
		
		int left = 1; //최초의 바구니 위치는 1임 
		int right = m; //바구니의 끝 위치 
		int cnt=0; //이동 횟수 카운트 
		
		for(int i=0; i<arr.length; i++) {
			if(right<arr[i]) { //내려오는 사과가 바구니보다 오른쪽에 있으면
				cnt+=arr[i]-right;
				left = arr[i]-m+1;//바구니 오른쪽 끝이 사과위치에 맞춰져야함 그래야 스크린 안튀어나감
				right=arr[i];
			}
			else if(arr[i]<left){ //사과가 바구니보다 왼쪽에 있음
				cnt+=left-arr[i];
				right = arr[i] +m -1;
				left=arr[i];
			}
			
			
		}
		System.out.println(cnt);
		
	}
}