땅지원
땅지원's Personal blog
땅지원
전체 방문자
오늘
어제
  • 전체 (353)
    • Frontend (2)
      • React (2)
    • Backend (90)
      • Java (16)
      • Python (19)
      • Spring (23)
      • Database (21)
      • Troubleshooting (8)
    • DevOps (27)
      • ELK (13)
    • CS (40)
    • OS (2)
      • Linux (2)
    • Algorithm (95)
      • concept (18)
      • Algorithm Problem (77)
    • 인공지능 (25)
      • 인공지능 (12)
      • 연구노트 (13)
    • 수업정리 (35)
      • 임베디드 시스템 (10)
      • 데이터통신 (17)
      • Linux (8)
    • 한국정보통신학회 (5)
      • 학술대회 (4)
      • 논문지 (1)
    • 수상기록 (8)
      • 수상기록 (6)
      • 특허 (2)
    • 삼성 청년 SW 아카데미 (6)
    • 42seoul (12)
    • Toy project (3)
    • 땅's 낙서장 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 20.11.6 BB21플러스 온라인 학술대회
  • 20.10.30 한국정보통신학회 온라인 학술대회

인기 글

태그

  • I
  • 이것이 리눅스다 with Rocky Linux9
  • D
  • ㅗ
  • E

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
땅지원

땅지원's Personal blog

Algorithm/Algorithm Problem

백준 17135 캐슬 디펜스(구현, 조합, BFS) ★★

2022. 8. 19. 15:45

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

 

17135번: 캐슬 디펜스

첫째 줄에 격자판 행의 수 N, 열의 수 M, 궁수의 공격 거리 제한 D가 주어진다. 둘째 줄부터 N개의 줄에는 격자판의 상태가 주어진다. 0은 빈 칸, 1은 적이 있는 칸이다.

www.acmicpc.net

단순 구현 문제인 줄 알고 쉽게 접근했지만 다양한 알고리즘을 사용해야 했던 문제였다.

1. 궁수의 위치를 정해야 하기 때문에 Combination 사용

2. 궁수가 공격을 해야하는데 동일한 거리의 적이 여러명 있으면 가장 왼쪽인 적을 죽인다

=> BFS를 통해 가장 가까운거리를 탐색하고 방향벡터를 [좌 상 우] 방향으로 탐색함으로써 가장 가까운 애들 중 가장 왼쪽에 있는 적을 탐색하게 만든다

why?)

만약 왼쪽에 적이 없었고 상, 우 자리에만 적이 있다면 상에 있는 적이 가장 왼쪽에 있는 적이 될 테니까

방향벡터를 [좌 상 우] 로 해줘야한다.

3. next_round()를 해서 행렬을 아래로 밀어주면 0행은 0으로 초기화가 된다.

4. 적이 궁수자리에 와도 게임이 끝나는게 아니라 제외된다.

5. 게임 라운드는 1행씩 아래로 밀리니까 총 n번 라운드만 진행된다

package practice;

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

public class Main_17135 {
	static int[][] board;
	static int ans, n, m, d, enemy;
	static int[] archer = new int[3];
	static int[] dx = { 0, -1, 0 };
	static int[] dy = { -1, 0, 1 };

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());
		d = Integer.parseInt(st.nextToken());

		board = new int[n + 1][m];

		for (int i = 0; i < n; i++) {
			st = new StringTokenizer(br.readLine());
			for (int j = 0; j < m; j++) {
				int temp = Integer.parseInt(st.nextToken());
				if (temp == 1)
					enemy++;
				board[i][j] = temp;
			}
		}

		combi(0, 0);

		System.out.println(ans);

	}

	public static void combi(int depth, int start) {
		if (depth == 3) {
			int[][] board_temp = new int[n + 1][m]; // 깊은복사
			for (int i = 0; i < n + 1; i++) {
				for (int j = 0; j < m; j++) {
					board_temp[i][j] = board[i][j];
				}
			}

			game(board_temp);

			return;
		}

		for (int i = start; i < m; i++) {
			archer[depth] = i;
			combi(depth + 1, i + 1);
		}
	}

	public static int distance(int x, int y, int x1, int y1) {
		return Math.abs(x - x1) + Math.abs(y - y1);
	}

	public static void next_round(int[][] board) {
		for (int i = n; i > 0; i--) {
			for (int j = 0; j < m; j++) {
				board[i][j] = board[i - 1][j];
			}
		}
		for (int i = 0; i < m; i++) {
			board[0][i] = 0; 
		}
	}

	public static boolean end_test(int cnt,int[][] board, int enemy_cnt) {
		if (enemy_cnt == enemy)
			return false;
		else if(cnt == n)
			return false;

		return true;
	}

	public static int attack(int[][] board) {
		int enemy_cnt = 0;

		for (int k = 0; k < 3; k++) {
			boolean[][] visited = new boolean[n + 1][m];
			Queue<int[]> queue = new ArrayDeque<>();

			queue.add(new int[] { n, archer[k], 0 });
			visited[n][archer[k]] = true;
			while (!queue.isEmpty()) {
				int[] poll = queue.poll();

				if (poll[2] > d)
					break;

				if (board[poll[0]][poll[1]] >= 1) {
					board[poll[0]][poll[1]] = 2;
					break;
				}

				for (int i = 0; i < 3; i++) {
					int nx = poll[0] + dx[i];
					int ny = poll[1] + dy[i];
					if ((0 <= nx) && (0 <= ny) && (nx < n) && (ny < m) && !visited[nx][ny]) {
						visited[nx][ny] = true;
						queue.add(new int[] { nx, ny, poll[2] + 1 });
					}
				}
			}
		}

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (board[i][j] == 2) {
					enemy_cnt++;
					board[i][j] = 0;
				}
			}

		}
		return enemy_cnt;
	}

	public static void game(int[][] board) {
		int enemy_cnt = 0;
		int cnt=0;
		while (end_test(cnt++,board, enemy_cnt)) {

			enemy_cnt += attack(board);
			next_round(board);

		}
		ans = Math.max(ans, enemy_cnt);
	}

}

'Algorithm > Algorithm Problem' 카테고리의 다른 글

백준 1956 운동(Floyd-Warshall)  (0) 2022.08.28
백준 1238 파티(최단경로 - 다익스트라)★★  (0) 2022.08.28
백준 1826 연료 채우기(우선순위 큐, 그리디)★★  (0) 2022.08.12
백준 최소 회의실 개수(우선순위 큐, 그리디)★★  (0) 2022.08.12
백준 17406 배열 돌리기4(구현)  (0) 2022.08.12
    'Algorithm/Algorithm Problem' 카테고리의 다른 글
    • 백준 1956 운동(Floyd-Warshall)
    • 백준 1238 파티(최단경로 - 다익스트라)★★
    • 백준 1826 연료 채우기(우선순위 큐, 그리디)★★
    • 백준 최소 회의실 개수(우선순위 큐, 그리디)★★
    땅지원
    땅지원
    신입 개발자의 우당탕탕 기술 블로그

    티스토리툴바