[SWEA] 5644. 무선충전

  • 메모리 : 22,628 KB
  • 실행시간 : 128 ms
  • 코드길이 : 3,221 B
  • 소요시간 : 4H
  • 사용자 A,B가 겹치는 부분 처리해주는게 까다로웠다. 처음에 메소드 하나로 해결하려다가 inSame()메소드를 만들어서 겹치는 부분 처리를 따로 계산하도록 했다.
  • inSame(int aBC, int bBC, Point personA, Point personB) 메소드는 사용자 A, B가 겹치는 경우 완탐을 통해서 성능을 더한 값 중에 최대값을 찾아서 리턴해주었다. 처음엔 문제에서 설명된 대로 단순히 생각했는데 문제에서 설명한 경우 외에 사용자 A, B가 같은 시간에 같은 영역에 있으면서 선택할 수 있는 BC가 여러 개 존재하는 경우 모든 조합 중에서 어떤 조합이 가장 큰 성능을 얻을 수 있는지 계산해주어야 했다.
  • 그 외에는 다 잘 구현했다고 생각했는데 continue를 적절히 사용하지 않아서 중복으로 값이 더해져서 더 큰 값이 나오는 등 자잘한 실수들이 좀 있었다. 그래도 이 문제는 문제에서 주어진 5개의 테스트 케이스를 잘 통과하면 한번에 PASS를 받을 수 있도록 테스트케이스가 잘 주어진 문제같다.
  • 무엇보다 혼자 끝까지 해결하고 풀었다는 점이 가장 뿌듯하다! ^__^
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Solution_5644_무선충전 {

	static int SIZE = 10;
	static int M, A, aBC, bBC;
	static int[] moveA;
	static int[] moveB;
	static int[][] BC;
	static int[][] map;

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = null;
		StringBuilder answer = new StringBuilder();

		int T = Integer.parseInt(in.readLine());
		for (int tc = 0; tc < T; tc++) {
			st = new StringTokenizer(in.readLine(), " ");
			M = Integer.parseInt(st.nextToken());
			A = Integer.parseInt(st.nextToken());
			map = new int[SIZE][SIZE];
			Point personA = new Point(0, 0);
			Point personB = new Point(SIZE - 1, SIZE - 1);
			moveA = new int[M + 1];
			moveB = new int[M + 1];
			BC = new int[A + 1][4];

			st = new StringTokenizer(in.readLine(), " ");
			for (int i = 1; i <= M; i++) {
				moveA[i] = Integer.parseInt(st.nextToken());
			}
			st = new StringTokenizer(in.readLine(), " ");
			for (int i = 1; i <= M; i++) {
				moveB[i] = Integer.parseInt(st.nextToken());
			}

			for (int i = 1; i <= A; i++) {
				st = new StringTokenizer(in.readLine(), " ");
				BC[i][0] = Integer.parseInt(st.nextToken()) - 1; // X좌표
				BC[i][1] = Integer.parseInt(st.nextToken()) - 1; // Y좌표
				BC[i][2] = Integer.parseInt(st.nextToken()); // 충전범위(C)
				BC[i][3] = Integer.parseInt(st.nextToken()); // 성능(P)
			}

			int result = 0;
			for (int i = 0; i <= M; i++) {
				aBC = movePerson(0, moveA[i], personA);
				bBC = movePerson(0, moveB[i], personB);
				if (aBC > 0 && bBC > 0 && aBC == bBC) { // 같을 경우 다른 충전 포인트 찾기
					result += inSame(aBC, bBC, personA, personB);
					continue;
				}
				result += BC[aBC][3] + BC[bBC][3];
			}

			answer.append('#').append(tc + 1).append(' ').append(result).append('\n');
		} // end test-case
		System.out.println(answer);
		in.close();
	} // end main

	private static int inSame(int aBC, int bBC, Point personA, Point personB) {
		int maxResult = BC[aBC][3];
		for (int i = 1; i < A + 1; i++) {
			int temp = 0;
			if (BC[i][2] >= (Math.abs(personA.x - BC[i][0]) + Math.abs(personA.y - BC[i][1]))) {
				aBC = i;
			}
			for (int j = 1; j < A + 1; j++) {
				if (BC[j][2] >= (Math.abs(personB.x - BC[j][0]) + Math.abs(personB.y - BC[j][1]))) {
					bBC = j;
					if (aBC == bBC)
						temp = BC[aBC][3];
					else
						temp = BC[aBC][3] + BC[bBC][3];

					if (maxResult < temp)
						maxResult = temp;
				}
			}
		}
		return maxResult;
	}

	private static int movePerson(int BCpoint, int dir, Point person) {
		switch (dir) {
		case 1: // 상
			person.y -= 1;
			break;
		case 2: // 우
			person.x += 1;
			break;
		case 3: // 하
			person.y += 1;
			break;
		case 4: // 좌
			person.x -= 1;
			break;
		}
		for (int i = 1; i < A + 1; i++) {
			if (BC[i][2] >= (Math.abs(person.x - BC[i][0]) + Math.abs(person.y - BC[i][1]))) {
				if (BC[BCpoint][3] < BC[i][3]) {
					BCpoint = i;
				}
			}
		}
		return BCpoint;
	}

	static class Point {
		int x;
		int y;

		public Point(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}
}

Leave a comment