https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRDL1aeugDFAUo

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

www.swexpertacademy.com

풀이

  1. 먼저 사용자들의 이동 정보를 각 배열에 저장하고 BC의 정보는 AP클래스를 만들어서 ArrayList에 저장하였다.
  2. 시간에 따라 이동하면서 각 시간마다 A와 B의 충전량 합의 최댓값을 구해준다.
    1. 최댓값은 사용자가 각각 사용할 수 있는 충전량을 배열에 저장해놓고 모든 경우를 구해줬다.
    2. 이때 i == j 인 상황이 됐을 때 한쪽은 0 (해당 BC를 사용할 수 없는 경우)일 수도 있으므로 무조건 반으로 나눠주면 안 되고 둘 다 해당 BC를 이용하고 있는지 확인해주어야 한다. (같은 p값을 가지는지 확인)
  3. 시간마다의 최댓값을 모두 더해준 후에 출력

 

import java.io.*;
import java.util.*;

public class Solution {
	static class AP {
		int x;
		int y;
		int c;
		int p;
		AP(int x, int y, int c, int p) {
			this.x = x;
			this.y = y;
			this.c = c;
			this.p = p;
		}
	}
	
	static int M,A;
	static int dx[] = {0,-1,0,1,0};
	static int dy[] = {0,0,1,0,-1};
	static int Ainfo[];
	static int Binfo[];
	static ArrayList aplist;
    
	public static void main(String[] args) throws IOException {
		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());
			A = Integer.parseInt(st.nextToken());
			Ainfo = new int[M];
			Binfo = new int[M];
			
            //사용자 A의 이동정보
			st = new StringTokenizer(br.readLine());
			for(int i=0; i<M; i++) {
				Ainfo[i] = Integer.parseInt(st.nextToken());
			}
			
            //사용자 B의 이동정보
			st = new StringTokenizer(br.readLine());
			for(int i=0; i<M; i++) {
				Binfo[i] = Integer.parseInt(st.nextToken());
			}
			
            //BC의 정보를 ArrayList에 저장한다.
			aplist = new ArrayList();
			for(int i=0; i<A; i++) {
				st = new StringTokenizer(br.readLine());
				
				int y = Integer.parseInt(st.nextToken());
				int x = Integer.parseInt(st.nextToken());
				int c = Integer.parseInt(st.nextToken());
				int p = Integer.parseInt(st.nextToken());
				
				aplist.add(new AP(x,y,c,p));
			}
			
			int ans = move();
			System.out.println("#"+tc+" "+ans);
		}
	}
	
    
	static int move() {
		int x1 = 1;
		int y1 = 1;
		int x2 = 10;
		int y2 = 10;
        
        //0초일때의 합
		int sum = getMax(x1,y1,x2,y2);
		
        //시간별로 이동하면서 그때마다의 최대값을 합해준다.
		for(int time=0; time<M; time++) {
			x1 += dx[Ainfo[time]];
			y1 += dy[Ainfo[time]];
			x2 += dx[Binfo[time]];
			y2 += dy[Binfo[time]];
			sum += getMax(x1,y1,x2,y2);
		}
		
		return sum;
	}
	
    
	static int getMax(int x1, int y1, int x2, int y2) {
		int[][] amount = new int[2][A];
		//2차원 배열에 사용자A(0)와 사용자B(1)의 BC별로 충전가능한 값을 저장해준다.
        
        //사용자A의 충전 가능한 BC의 p값
		for(int j=0; j<A; j++) {
				amount[0][j] = check(x1,y1,j);
		}
		
        //사용자B의 충전 가능한 BC의 p값
		for(int j=0; j<A; j++) {
			amount[1][j] = check(x2,y2,j);
			
		}
		
        //사용자 A와 사용자 B의 충전량의 합중 최댓값을 구해준다.
		int max = 0;
		for(int i=0; i<A; i++) {
			for(int j=0; j<A; j++) {
				int sum = amount[0][i]+amount[1][j];
                
                 // 같은 BC를 이용하는 경우 값을 반으로 나눠줘야한다.
                 // 주의할 점은 한 쪽은 아예 값이 0일수도 있으므로(해당 BC를 이용할 수 없는 위치) 정확히 둘다 같이 이용하고 있는 경우에만 나누어주어야한다.
				if(i == j && amount[0][i] == amount[1][j])
					sum /= 2;
				if(sum > max) max = sum;
			}
		}

		return max;
	}
	
	static int check(int x, int y, int apnum) {

		int a = Math.abs(x-aplist.get(apnum).x);
		int b = Math.abs(y-aplist.get(apnum).y);
		int dist = a+b;
        
        //해당 BC에 포함되는 경우에 p값을 리턴
		if(dist <= aplist.get(apnum).c)
			return aplist.get(apnum).p;
		else
			return 0;
	}
	
}

+ Recent posts