728x90

https://www.acmicpc.net/problem/21610

 

21610번: 마법사 상어와 비바라기

마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기

www.acmicpc.net


풀이 방법

비구름을 이동했을 때, 그 위치가 배열을 벗어나면 어떻게 처리할 것인지가 가장 핵심인 것 같다.

수정중..

 

자바 코드

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

public class Main {
	static class Cloud{
		int x,y;

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

		@Override
		public String toString() {
			return "Cloud [x=" + x + ", y=" + y + "]";
		}
		
		
	}
	static StringTokenizer st;
	static int N,M;
	static int cDir[][]= {{},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1}};
	static int dir[][]= {{-1,-1},{-1,1},{1,1},{1,-1}};
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		st = new StringTokenizer(br.readLine());
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		
		int[][] map=new int[N+1][N+1];
		int[][] ori=new int[N+1][N+1];
		
		for (int i = 1; i < N+1; i++) {
			st = new StringTokenizer(br.readLine());
			for (int j = 1; j < N+1; j++) {
				map[i][j]=Integer.parseInt(st.nextToken());
				ori[i][j]=map[i][j];
			}
		}
		
		int[][] mList=new int[M][2];
		for (int m = 0; m < M; m++) {
			st = new StringTokenizer(br.readLine());
			mList[m][0]=Integer.parseInt(st.nextToken());
			mList[m][1]=Integer.parseInt(st.nextToken());
		}
		
//		System.out.println(Arrays.deepToString(map));
		
		// 구름의 위치가 들어 갈 
		Queue<Cloud> cloud=new LinkedList<>();
		
		// 초기위치 넣어줌
		cloud.add(new Cloud(N, 1));
		cloud.add(new Cloud(N, 2));
		cloud.add(new Cloud(N-1, 1));
		cloud.add(new Cloud(N-1, 2));
		
		int result=0;
		
		// 방문한 구름의 위치 표시
		boolean visited[][]=new boolean[N+1][N+1];
//		visited[N][1]=true;
//		visited[N][2]=true;
//		visited[N-1][1]=true;
//		visited[N-1][2]=true;
//		
		// M만큼 반복
		for (int t = 0; t < M; t++) {
			visited=new boolean[N+1][N+1];
			int d=mList[t][0]; //방향
			int s=mList[t][1]; //이동거리
			int size=cloud.size();
			// 현재 위치한 구름만큼만 반복
			while(size-->0) {
				Cloud c=cloud.poll();
				int x=c.x;
				int y=c.y;
//				System.out.println("처리중인 구름 x::"+x+" y::"+y);
				// 이동
				int nx=0;
				int ny=0;
				
				if((x+cDir[d][0]*s)%N<=0) {
					nx=(x+cDir[d][0]*s)%N+N;
				}else {
					nx=(x+cDir[d][0]*s)%N;
				}
				if((y+cDir[d][1]*s)%N<=0) {
					ny=(y+cDir[d][1]*s)%N+N;
				}else {
					ny=(y+cDir[d][1]*s)%N;
				}
				
//				System.out.println("구름위치 x::"+nx+" y::"+ny);
				map[nx][ny]+=1; // 구름으로 만들어줌
				visited[nx][ny]=true;
				cloud.add(new Cloud(nx, ny));
			}
			
			while(!cloud.isEmpty()) {
				Cloud c=cloud.poll();
				int x=c.x;
				int y=c.y;
				// 대각선 이동
				int cnt=0;
				for (int i = 0; i < 4; i++) {
					int nx=x+dir[i][0];
					int ny=y+dir[i][1];
					if(isOkayX(nx) && isOkayY(ny) && map[nx][ny]>0) cnt++;
				}
				
				map[x][y]+=cnt; // 대각선에 물 있는지 여부만큼 더해줌
			}
		
			// 이동 끝
			// 물의 양 2이상 -> 구름 생김 && 물 양 -2
			for (int i = 1; i < N+1; i++) {
				for (int j = 1; j < N+1; j++) {
					if(!visited[i][j]&&map[i][j]>=2) {
						cloud.add(new Cloud(i, j));
						map[i][j]-=2;
					}
				}
			}
			
			// 값 확인용
			if (t==M-1) {
				for (int i = 1; i < N+1; i++) {
					for (int j = 1; j < N+1; j++) {
						result+=map[i][j];
					}
				}
			}
		}
		System.out.println(result);
		
	}
	private static boolean isOkayX(int nx) {
		// TODO Auto-generated method stub
		return nx>0 && nx<=N;
	}
	private static boolean isOkayY(int ny) {
		// TODO Auto-generated method stub
		return ny>0 && ny<=N;
	}

}

728x90

'알고리즘 > 백준 BOJ' 카테고리의 다른 글

[JAVA] 백준 3020 개똥벌레  (0) 2021.10.06
[JAVA] 백준 1697 숨바꼭질  (0) 2021.09.23
[JAVA] 백준 21608 상어 초등학교  (0) 2021.09.18
[JAVA] 백준 2636 치즈  (0) 2021.09.15
[JAVA] 백준 1753 최단경로  (0) 2021.09.14
복사했습니다!