본문 바로가기

[Algorithms]/[Problems]

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

728x90

    시간이 조금 남아서 삼성에서 낸 구현문제를 풀어보았다. 매일같이 풀던 알고리즘 문제를 한 2주 쉬었더니 또 그렇게 낯설다ㅎㅎ. 문제는 어렵지 않고, 요구하는 내용을 그대로 구현하기만 하면 된다. 다양하게, 또 습관처럼 사용하지 않으면 금새 낯설어지는게 프로그래밍 언어인것 같다. 나만 그런가 했는데, 근래에 본 면접장에서 면접관님들께서도 그렇다 하셨다. 현업 최정상급 고수분들이시지만(물론 긴장을 풀어주시려는 의도일 것이다^^) 그렇게 겸손하게 말씀하시는 걸 보고 많은 것을 느꼈다. 꾸준하게 사용하고, 갈고 닦아야 그 언어를 그 언어'답게' 사용할 수 있는 것 같다.  

 

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

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

www.acmicpc.net

in java,

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class Main {

	static int n,m;
	static int[][] map;
	static int[][] move;
	static boolean[][] check;
	
	static int[] dy = {0, 0,-1,-1,-1, 0, 1, 1, 1};
	static int[] dx = {0,-1,-1, 0, 1, 1, 1, 0,-1};
	
	static int[] ddy = {-1,-1, 1, 1};
	static int[] ddx = {-1, 1, 1,-1};
	
	static ArrayList<Pos> storm  = new ArrayList<Pos>();
	static class Pos{
		int y, x;
		public Pos(int y, int x) {
			this.y = y;
			this.x = x;
		}
	}
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));	
		StringTokenizer st = null;
		st = new StringTokenizer(br.readLine());
		
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());
		map = new int[n+1][n+1];
		check = new boolean[n+1][n+1];
		move = new int[m][2];
		
		for(int i=1; i<=n; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j=1; j<=n; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		for(int i=0; i<m; i++) {
			st = new StringTokenizer(br.readLine());
			move[i][0] = Integer.parseInt(st.nextToken());
			move[i][1] = Integer.parseInt(st.nextToken());
		}
		
		// init
		storm.add(new Pos(n-1,1));
		storm.add(new Pos(n-1,2));
		storm.add(new Pos(n,1));
		storm.add(new Pos(n,2));
		
		for(int i=0; i<m; i++) {
			int d = move[i][0]; // 방향
			int s = move[i][1]; // 거리
			// storm 돌면서 이동해서 +1
			for(int c=0; c<storm.size(); c++) {
				int ny = newValue(storm.get(c).y, dy[d]*s);
				storm.get(c).y = ny;
				int nx = newValue(storm.get(c).x, dx[d]*s);
				storm.get(c).x = nx;
				check[ny][nx] = true;
				map[ny][nx]++;
			}
			// 현재위치에서 4방위 체크
			for(int c=0; c<storm.size(); c++) {
				int cnt = 0;
				for(int dd=0; dd<4; dd++) {
					int ny = storm.get(c).y + ddy[dd];
					int nx = storm.get(c).x + ddx[dd];
					if(checkBound(ny, nx) && map[ny][nx]>0) {
						cnt++;
					}
				}
				map[storm.get(c).y][storm.get(c).x] += cnt;
			}
			// 이동후 위치 전부 +1, 체크하고 나면 storm은 초기화
			storm.clear();
			for(int p=1; p<=n; p++) {
				for(int q=1; q<=n; q++) {
					if(map[p][q] >= 2 && !check[p][q]) {
						storm.add( new Pos(p,q));
						map[p][q] -= 2;
					}
				}
			}
			// 마지막으로 체크부분 초기화
			check = new boolean[n+1][n+1];
		}
		System.out.println(rainSum());
	}
	
	private static boolean checkBound(int y, int x) {
		return (y>=1 && y<=n && x>=1 && x<=n) ? true : false;
	}
	
	private static int newValue(int oldValue, int offset) {
		int nv = (oldValue + offset)%n;
		return (nv <= 0) ? nv+n : nv;
	}
	
	private static int rainSum() {
		int sum=0;
		for(int i=1; i<=n; i++) {
			for(int j=1; j<=n; j++) {
				sum += map[i][j];
			}
		}
		return sum;
	}

}

in python,

# simple implementation
def newValue(old, offSet):
    new = (old + offSet) % n
    return new + n if new < 0 else new


# direction
dy = [0, -1, -1, -1, 0, 1, 1, 1]
dx = [-1, -1, 0, 1, 1, 1, 0, -1]
ddy = [-1, -1, 1, 1]
ddx = [-1, 1, 1, -1]

# data input
n, m = map(int, input().split())
table = [list(map(int, input().split())) for _ in range(n)]
move = []
for i in range(m):
    tmp = list(map(int, input().split()))
    move.append([tmp[0] - 1, tmp[1]])

# storm init
storms = [[n - 2, 0], [n - 2, 1], [n - 1, 0], [n - 1, 1]]

# moves
for i in range(m):
    d = move[i][0]  # 방향
    s = move[i][1]  # 거리
    # 돌면서 이동해서 +1

    next_storms = []
    check = [[False] * n for _ in range(n)]

    for storm in storms:
        ny = newValue(storm[0], dy[d] * s)
        nx = newValue(storm[1], dx[d] * s)
        check[ny][nx] = True
        table[ny][nx] += 1
        next_storms.append([ny, nx])

    for storm in next_storms:
        cnt = 0
        for d in range(4):
            ny = storm[0] + ddy[d]
            nx = storm[1] + ddx[d]
            if 0 <= ny < n and 0 <= nx < n and table[ny][nx] > 0:
                cnt += 1
        table[storm[0]][storm[1]] += cnt

    storms.clear()
    for i in range(n):
        for j in range(n):
            if table[i][j] >= 2 and check[i][j] == False:
                table[i][j] -= 2
                storms.append([i, j])

ans = 0
for i in range(n):
    ans += sum(table[i])

print(ans)
728x90

'[Algorithms] > [Problems]' 카테고리의 다른 글

BOJ.2931번.가스관  (0) 2021.06.27
BOJ. 1766번.문제집  (0) 2021.06.24
BOJ. 2042번. 구간합 구하기  (0) 2021.05.16
PGM. 신규아이디 추천  (0) 2021.05.05
BOJ. 1194번. 달이 차오른다 가자  (0) 2021.04.21