1. 문제
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
2. 접근방법
시뮬레이션 문제이다.
먼저 BC의 정보들을 나타내기 위해
1 . 각 BC에 번호를 지정해 배열하나에 충전세기를 저장해두고
2. List형태의 map을 만들어
3. BC의 위치부터 범위만큼 bfs를 돌리며 값들을 해당 좌표의 List에 저장했다.
그 다음 A와 B를 이동 시키는데
각각 이동 시킨 위치에서 신호의 최댓값을 가진 BC의 번호를 찾는다
이후 A와 B가 같은 BC의 값을 가지고 있다면
1) A와 B 둘 다 2개 이상의 신호를 받을 수 있는 경우
이 땐 처음 찾은 BC를 제외한
다른 A위치의 최댓값과
다른 B위치의 최댓값
2개를 비교해 더 큰 값을 가진 얘의 값만 새로 찾은 BC로 바꿔준다.
2) A나 B 둘중 한명만 2개이상의 신호를 받는 경우
무조건 2개 이상을 받는 친구가
처음 찾은 BC를 제외한
다른 최댓값을 찾아 바꾼다.
3) 둘 다 최초 찾은 BC만 신호를 받는 경우
이 경우 A와 B가 반반 받으니
총 받는 값은 1명이 다 받는것과 같아지므로
그냥 B의 값을 0으로 설정했다.
------
이 방식으로 M번 만큼 시뮬을 돌리면 정답이 나오게 된다.
3. 자바 코드
package D4;
import java.awt.Point;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
public class P5644무선충전 {
static List<Integer> map[][];
static int bcinfo[];
static int moveA[], moveB[], M;
static Point A, B;
static int score;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
for (int tc = 1; tc <= T; tc++) {
StringTokenizer st = new StringTokenizer(br.readLine());
M = Integer.parseInt(st.nextToken()); // time
int Ap = Integer.parseInt(st.nextToken()); // Ap cnt
map = new List[10][10];
bcinfo = new int[Ap + 1];
score = 0;
moveA = new int[M];
moveB = new int[M];
StringTokenizer st1 = new StringTokenizer(br.readLine());
StringTokenizer st2 = new StringTokenizer(br.readLine());
for (int i = 0; i < M; i++) {
moveA[i] = Integer.parseInt(st1.nextToken()) - 1;
moveB[i] = Integer.parseInt(st2.nextToken()) - 1;
}
for (int i = 1; i <= Ap; i++) {
st = new StringTokenizer(br.readLine());
int y = Integer.parseInt(st.nextToken()) - 1;
int x = Integer.parseInt(st.nextToken()) - 1;
int c = Integer.parseInt(st.nextToken());
int p = Integer.parseInt(st.nextToken());
bcinfo[i] = p;
spread(x, y, c, i);
}
A = new Point(0, 0);
B = new Point(9, 9);
go();
System.out.println("#" + tc + " " + score);
}
}
static int dr[] = { -1, 0, 1, 0 };
static int dc[] = { 0, 1, 0, -1 };
static void go() { // 점수 올리고 이동하고
for (int i = 0; i <= M; i++) {
List<Integer> Anum = map[A.x][A.y];
List<Integer> Bnum = map[B.x][B.y];
int sumA = findMax(Anum, -1);
int sumB = findMax(Bnum, -1);
if (sumA != 0 && sumA == sumB) {
if (Anum.size() > 1 && Bnum.size() > 1) {
int a = findMax(Anum, sumA);
int b = findMax(Bnum, sumB);
if (bcinfo[a] > bcinfo[b])
sumA = a;
else
sumB = b;
} else if (Anum.size() > 1) {
sumA = findMax(Anum, sumA);
} else if (Bnum.size() > 1) {
sumB = findMax(Bnum, sumB);
} else {
sumA = sumA;
sumB = 0;
}
}
score += bcinfo[sumA];
score += bcinfo[sumB];
if (i == M)
break;
if (moveA[i] != -1) {
A = new Point(A.x + dr[moveA[i]], A.y + dc[moveA[i]]);
}
if (moveB[i] != -1) {
B = new Point(B.x + dr[moveB[i]], B.y + dc[moveB[i]]);
}
}
}
static int findMax(List<Integer> nums, int ex) {
int max = 0;
if (nums != null) {
for (int i : nums) {
if (i != ex && bcinfo[max] < bcinfo[i])
max = i;
}
}
return max;
}
static void spread(int x, int y, int c, int num) { // 맵 만들기
Queue<Point> que = new LinkedList<Point>();
boolean visited[][] = new boolean[10][10];
visited[x][y] = true;
que.offer(new Point(x, y));
int dist = 0;
while (!que.isEmpty()) {
int size = que.size();
for (int i = 0; i < size; i++) {
Point now = que.poll();
if (map[now.x][now.y] == null) {
map[now.x][now.y] = new ArrayList<Integer>();
}
map[now.x][now.y].add(num);
for (int d = 0; d < 4; d++) {
int row = now.x + dr[d];
int col = now.y + dc[d];
if (row < 0 || col < 0 || row >= 10 || col >= 10)
continue;
if (visited[row][col])
continue;
visited[row][col] = true;
que.offer(new Point(row, col));
}
}
if (dist == c) {
break;
}
dist++;
}
}
}
4. 마치며
그렇게 어려운 부분은 없었는데 조금 신선하게 느껴지긴 한 문제였다.
'알고리즘 문제풀이 > SWEA' 카테고리의 다른 글
[SWEA] 1868 파핑파핑 지뢰찾기 (0) | 2020.11.05 |
---|---|
[SWEA] 5643 키순서 (0) | 2020.11.04 |
[SWEA] 1949 등산로조성 (BFS로 풀어보기) (0) | 2020.11.03 |
[SWEA] 5656 벽돌깨기 (0) | 2020.11.03 |
[SWEA] 1952 수영장 (0) | 2020.10.30 |