본문 바로가기

[Algorithms]/[Problems]

BOJ. 20056번. 마법사 상어와 파이어볼

728x90

 

이번주는 상어문제들을 종합적으로 풀어보기로 했다.
구현문제들은 주로 조건에 따라 코드만 세심하게 살펴 짜면 통과받는데는 크게 어려움이 없다.
( 코드가 이쁘지 않은것이 함정;; )

 

www.acmicpc.net/problem/20056

 

20056번: 마법사 상어와 파이어볼

첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치

www.acmicpc.net

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer st;
	
	static int n,m,k,ans;
	static int[] dy = {-1,-1, 0, 1, 1, 1, 0,-1};
	static int[] dx = { 0, 1, 1, 1, 0,-1,-1,-1};
	static Queue<Fb>[][] map;
	
	static class Fb{
		int m,s,d;
		public Fb(int m, int s, int d) {
			this.m = m;
			this.s = s;
			this.d = d;
		}	
	}
	
	private static void moveFireBall() {
		Queue<Fb>[][] mmap = new LinkedList[n][n];
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < n; j++) {
				mmap[i][j] = new LinkedList<Fb>();
			}
		}
	   for(int i = 0; i < n; i++) {
	        for(int j = 0; j < n; j++) {	
	        	if(map[i][j].isEmpty()) continue;
	        	// 존재하는 경우
		        while(!map[i][j].isEmpty()) {
		        	Fb cur = map[i][j].poll();
		        	int nr = (i+dy[cur.d]*cur.s)%n;
		            int nc = (j+dx[cur.d]*cur.s)%n;
		            nr = (nr<0) ? nr+n : nr;
		            nc = (nc<0) ? nc+n : nc;
//		            System.out.println(nr + " " + nc);
		            mmap[nr][nc].add(new Fb(cur.m, cur.s, cur.d ));
		        }
	       }
	   }
	   map = mmap;
	}
	
	private static void splitFireBall() {
		for(int i = 0; i < n; i++) {
	        for(int j = 0; j < n; j++) {
	        	if(map[i][j].size()<=1) continue;
	        	int dOdd=0,dEven=0,mSum=0,sSum=0;
	        	int size = map[i][j].size();
	        	while(!map[i][j].isEmpty()) {
	        		Fb cur = map[i][j].poll();
	        		if(cur.d%2==1) {
	        			dOdd++;
	        		}else{
	        			dEven++;
	        		}
	        		mSum += cur.m;
	        		sSum += cur.s;
	        	}
	        	int nm = mSum/5;
	        	int ns = sSum/size;
	        	if(nm!=0) {
	        		if(dOdd==0 || dEven==0) {
	        			map[i][j].add(new Fb(nm,ns,0));
	        			map[i][j].add(new Fb(nm,ns,2));
	        			map[i][j].add(new Fb(nm,ns,4));
	        			map[i][j].add(new Fb(nm,ns,6));
	        		}else {
	        			map[i][j].add(new Fb(nm,ns,1));
	        			map[i][j].add(new Fb(nm,ns,3));
	        			map[i][j].add(new Fb(nm,ns,5));
	        			map[i][j].add(new Fb(nm,ns,7));
	        		}
	        	}
	        	
	        }
		}
	}
	
	public static void main(String[] args) throws IOException {
		st = new StringTokenizer(br.readLine());
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());
		k = Integer.parseInt(st.nextToken());
		map = new LinkedList[n][n];
		for(int i=0; i<n; i++) {
			for(int j=0; j<n; j++) {
				map[i][j] = new LinkedList<Fb>();
			}
		}
		for(int i=0; i<m; i++) {
			st = new StringTokenizer(br.readLine());
			int r = Integer.parseInt(st.nextToken())-1;
			int c = Integer.parseInt(st.nextToken())-1;
			int m = Integer.parseInt(st.nextToken());
			int s = Integer.parseInt(st.nextToken());
			int d = Integer.parseInt(st.nextToken());
			map[r][c].add(new Fb(m,s,d));
		}
		for(int time=0; time<k; time++) {
			moveFireBall();
			splitFireBall();
		}
		for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++){
                for(Fb fb : map[i][j]) {
                	ans += fb.m;
                }
            }
        }
		System.out.println(ans);
	}

}
728x90