본문 바로가기

알고리즘 문제풀이/백준

[백준][JAVA] 2564 - 경비원

문제 출처 : https://www.acmicpc.net/problem/2564

 

2564번: 경비원

첫째 줄에 블록의 가로의 길이와 세로의 길이가 차례로 주어진다. 둘째 줄에 상점의 개수가 주어진다. 블록의 가로의 길이와 세로의 길이, 상점의 개수는 모두 100이하의 자연수이다. 이어 한 줄

www.acmicpc.net

 

 

 

 

문제

 

 

 

설명

코드를 구현하는 데 복잡한 로직이나 알고리즘이 필요하진 않지만, 문제를 푸는 데 있어 아이디어를 생각해야 하는 유형의 문제였습니다. 제 아이디어는 다음과 같습니다.

 

① 동근이와 상점의 방향이 같거나, 남서, 남동, 서북, 북동이라면 일반 거리계산(맨해튼 거리계산)이 최소 거리입니다.

② 하지만 남북, 서동일 경우 시계 또는 반시계방향 거리를 모두 구해 둘 중 최소인 것을 골라야 합니다.

시계방향일 경우, 입력된 거리를 그냥 더하면 되고 반시계방향일 경우 가로/세로 위치에서 거리 뺀 것을 더하면 됩니다.

 

동근이와 상점이 각각 어떤 방향에 있는지 구별하기 위해서, 두 방향의 값을 곱한 값에 따라 조건을 분기 했습니다. 

①의 경우 곱의 결과가 2보다 크고 10보다는 작은 값들이고, ②의 경우 2 또는 12인 점을 이용했습니다.

 

 

 

 

코드

import java.util.Scanner;

public class BOJ2564_Security {

	static int W, H;
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		W = sc.nextInt(); //가로 길이
		H = sc.nextInt(); //세로 길이
		//블록을 R+1 by C+1의 이차원 배열이라 생각
		int sum=0;
		int N = sc.nextInt();//상점의 갯수
		Position[] shops = new Position[N];
		
		int dir, dist=0;
		for(int i=0; i<N; i++) {
			dir = sc.nextInt();
			dist = sc.nextInt();
			shops[i] = SetPos(dir, dist);
		} //상점의 정보 저장
		
		dir = sc.nextInt();
		dist = sc.nextInt();
		Position dg = SetPos(dir, dist); //동근의 정보 저장
		//입력 완료
		
		for(int i=0; i<N; i++) {
			Position shop = shops[i];
			if(dg.dir == shop.dir || ((2<dg.dir*shop.dir) && (10>dg.dir*shop.dir))) {
				//동근이와 상점이 방향이 같거나, 남서/남동/서북/북동이라면 -> 일반 거리계산
				sum +=(Math.abs(dg.x - shop.x) + Math.abs(dg.y-shop.y));
			} else { // 남북/서동일 경우 -> 시계, 반시계 해봐야 함
				int dist1=0, dist2=0;
				
				if(dg.dir * shop.dir==2) { //남북일 경우
					dist1 = dg.dist + shop.dist + H;
					dist2 = (W-dg.dist) + (W-shop.dist) + H;
				} else { //서동일 경우
					dist1 = dg.dist + shop.dist + W;
					dist2 = (H-dg.dist) + (H-shop.dist) + W;
				}
				sum += Math.min(dist1, dist2);
			}
		}
		System.out.println(sum);
	}
	
	
	private static Position SetPos(int dir, int dist) { //방향에 따른 위치 좌표 설정
		
		if(dir==1) { //북쪽이면
			return new Position(0, dist, dir, dist);
		} else if (dir==2) { //남쪽이면
			return new Position(H, dist, dir, dist);
		} else if(dir==3) { //서쪽이면
			return new Position(dist, 0, dir, dist);
		} else { //동쪽이면
			return new Position(dist, W, dir, dist);
		}
	}

	static class Position{ //x, y 위치좌표, 방향, 거리
		int x, y;
		int dir, dist;
		public Position(int x, int y, int dir, int dist) {
			super();
			this.x = x;
			this.y = y;
			this.dir = dir;
			this.dist = dist;
		}
	}
}