๊ตฌํ + bfs
ํ์ด๊ณผ์
0. ๋ชจ๋ํ๋ ํจ์๋ฅผ ๋ค ํธ์ถํ๋ solveํจ์.
static void solve(int n,int d) {
if(knights[n].isOut) return;
// 1. ํด๋น ๋ฐฉํฅ์ผ๋ก ์ด๋์ด ๊ฐ๋ฅํ์ง ํ์ธํ๊ธฐ
if(!movable(n,d)) return;
// 2. ์ด๋์ํค๊ธฐ
moved = new boolean[N+1];
move(n, d);
moved[n] = false; // ๋ช
๋ น๋ฐ์ n๋ฒ ๊ธฐ์ฌ๋ ์์ง์์์ ์ ์ธ
// 3. ๋ฐ๋ฏธ์ง ๊ณ์ฐํ๊ธฐ (๋ช
๋ น์ ๋ฐ์ n๋ฒ ๊ธฐ์ฌ๋ ๋ฐ๋ฏธ์ง๋ฅผ ์
์ง ์์)
calcDamage();
}
์ด๋ move(n,d); ํจ์๋ฅผ ํธ์ถํ ๋ค move[n] ์ false๋ก ํด์ค์ด์ ๋, ๋ฌธ์ ์กฐ๊ฑด์์ ์์ง์ธ ์ฒด์ค์ ๋ํด์๋ ๋ฐ๋ฏธ์ง๋ฅผ ๊ณ์ฐํ์ง ์๋๋ค๊ณ ๋ช ์๋์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
์๋๋ถํฐ๋ solveํจ์ ๋ด๋ถ์ ์ผ๋ก ํธ์ถํ๋ ๋ชจ๋ํ ๋ ํจ์ ์ ๋๋ค.
1. n๋ฒ ๊ธฐ์ฌ๋ฅผ d๋ฐฉํฅ์ผ๋ก ์์ง์ผ ์ ์๋์ง ํ์ธํ๋ movable ํจ์
static boolean movable(int n,int d) { // n๋ฒ ๊ธฐ์ฌ๋ฅผ d๋ฐฉํฅ์ผ๋ก ์ด๋์ํฌ ์ ์๋์ง ํ์ธ
Deque<int[]> q = new ArrayDeque<>();
Knight knight = knights[n];
for(int r=knight.r; r<knight.r+knight.h; r++) {
for(int c=knight.c; c<knight.c+knight.w; c++) {
q.offer(new int[] {r,c,n});
}
}
while(!q.isEmpty()) {
int[] cur = q.pollFirst();
int cr = cur[0];
int cc = cur[1];
int ck = cur[2]; // ํ์ฌ ํ์์ค์ธ ๊ธฐ์ฌ
int nr = cr + dr[d]; // d ๋ฐฉํฅ
int nc = cc + dc[d];
if(nr<0 || nr>=L || nc<0 || nc>=L || map[nr][nc]==2) return false; // ๋ฒฝ์ ๋ง๋๋ฉด ์ด๋ํ์ง ๋ชปํจ
if(knight_map[nr][nc]==ck) continue;
if(knight_map[nr][nc]==0) continue;
// ํ์์ค์ธ ๊ธฐ์ฌ์ ๋ค๋ฅธ ๊ธฐ์ฌ๋ฅผ ๋ง๋๋ฉด ํ์ ํด๋น ๊ธฐ์ฌ๋ค ๋ค ๋ฃ์ด์ฃผ๊ธฐ
if(knight_map[nr][nc]!=ck) {
bfs(nr,nc,q);
}
}
return true;
}
d ๋ฐฉํฅ์ ๋ฒฝ์ด ์์ผ๋ฉด(์์ง์ด์ง ๋ชปํ๋ฉด) false๋ฅผ ๋ฆฌํดํฉ๋๋ค.
d ๋ฐฉํฅ์ด ํ์ฌ ํ์ํ๋ ๊ธฐ์ฌ์์ญ์ด๋ผ๋ฉด continueํด์ผ ํฉ๋๋ค.
d๋ฐฉํฅ์ด ํ์ฌ ํ์์ค์ธ ๊ธฐ์ฌ์ ๋ค๋ฅธ ๊ธฐ์ฌ๋ผ๋ฉด ํด๋น ๊ธฐ์ฌ๋ค์ ํ์ ๋ค ๋ฃ์ด์ค์ผ ํฉ๋๋ค.
์ด๋ฅผ ์ํด์ bfsํจ์ ํธ์ถํ๊ณ , ๋งค๊ฐ๋ณ์๋ก ํ์ฌ ํ๋ฅผ ๋ฃ์ด์คฌ์ต๋๋ค.
movable ํจ์ ๋๊น์ง ๋๋ฌํ๋ค๋ฉด, ํด๋น ๊ธฐ์ฌ๋ฅผ ์์ง์ผ ์ ์๋ค๋ ์๋ฏธ์ด๋ฏ๋ก true๋ฅผ ๋ฆฌํดํด์ค๋๋ค.
movable ํจ์์์ ๋ด๋ถ์ ์ผ๋ก ํธ์ถํ๋ bfsํจ์
static void bfs(int r,int c, Deque<int[]> q) { // ์ด๋ํ๋ ค๋ ๊ธฐ์ฌ์ ์ธ์ ํ ๊ธฐ์ฌ๋ค์ ํ์ ๋ฃ์ด์ฃผ๋ BFSํจ์
boolean[][] bfs_visited = new boolean[L][L];
Deque<int[]> bfs_q = new ArrayDeque<>();
bfs_visited[r][c] = true;
bfs_q.offer(new int[] {r,c,knight_map[r][c]});
// movable ํ ์
๋ฐ์ดํธ
q.offer(new int[] {r,c,knight_map[r][c]});
while(!bfs_q.isEmpty()) {
int[] cur = bfs_q.pollFirst();
int cr = cur[0];
int cc = cur[1];
int ck = cur[2]; // ํ์ฌ ํ์์ค์ธ ๊ธฐ์ฌ
for(int d=0;d<4;d++) {
int nr = cr + dr[d];
int nc = cc + dc[d];
if(nr<0 || nr>=L) continue;
if(nc<0 || nc>=L) continue;
if(bfs_visited[nr][nc]) continue;
if(knight_map[nr][nc]==ck) {
bfs_visited[nr][nc] = true;
bfs_q.offer(new int[] {nr,nc,ck});
// movable ํ ์
๋ฐ์ดํธ
q.offer(new int[] {nr,nc,ck});
}
}
}
}
bfs๋ฅผ ํตํด ๋งค๊ฐ๋ณ์๋ก ๋๊ฒจ์ค ์ฒด์ค ์์ญ์ ์ฐพ๊ณ , ๊ทธ ์ขํ๋ค์ ๋งค๊ฐ๋ณ์๋ก ๋๊ฒจ์ค ํ์ ๋ฃ์ด์ฃผ๋ ํจ์์ ๋๋ค.
2. ์์ง์ด๋ ํจ์ move
static void move(int n,int d) {
Knight knight = knights[n];
moved[n] = true;
for(int i=knight.r;i<knight.r+knight.h;i++) {
for(int j=knight.c;j<knight.c+knight.w;j++) {
int nr = i + dr[d];
int nc = j + dc[d];
// nr, nc์์น์ ๋ ๋ค๋ฅธ ๊ธฐ์ฌ๊ฐ ์์ผ๋ฉด ๊ทธ ๊ธฐ์ฌ๋ค ์ด๋์ํค๊ธฐ
if(knight_map[nr][nc]!=0 && knight_map[nr][nc]!=n) {
move(knight_map[nr][nc],d);
}
}
}
// ์ด๋์ํค๊ธฐ
for(int i=knight.r;i<knight.r+knight.h;i++) {
for(int j=knight.c;j<knight.c+knight.w;j++) {
knight_map[i][j] = 0;
}
}
for(int i=knight.r;i<knight.r+knight.h;i++) {
for(int j=knight.c;j<knight.c+knight.w;j++) {
int nr = i + dr[d];
int nc = j + dc[d];
knight_map[nr][nc] = n;
}
}
knight.r += dr[d];
knight.c += dc[d];
}
๊ธฐ์ฌ๋ค์ ์ฐ์์ ์ผ๋ก ์์ง์ด๋ฏ๋ก, ์ฌ๊ท๋ฅผ ํ์ฉํ์ต๋๋ค.
nr,nc์์น์ ๋ ๋ค๋ฅธ ๊ธฐ์ฌ๊ฐ ์๋ค๋ฉด ๊ทธ ๊ธฐ์ฌ๋ค์ ์ด๋ ์ํจ ํ์ ํ์ฌ ๊ธฐ์ฌ๋ค์ ์์ง์ด๊ณ knight ๊ฐ์ฒด์ ์ขํ๋ํ ์ ๋ฐ์ดํธ ์์ผ์ค๋๋ค.
์ฌ๊ท๋ ์คํ ์๋ฃ๊ตฌ์กฐ์ ์ผ์นํฉ๋๋ค(์ ์ ํ์ถ). ๋ฐ๋ผ์ ์ ์ผ ๋ง์ง๋ง ๊ธฐ์ฌ๋ค ๋ถํฐ ์์ง์ด๊ฒ ๋๋ฏ๋ก ์์ ๊ฐ์ด ๊ตฌํํ ์ ์์์ต๋๋ค.
๋ํ moved๋ณ์๋ฅผ true๋ก ์ค์ ํด์คฌ๋๋ฐ, ์ด๋ 3๋ฒ์์ ํ ๋ฐ๋ฏธ์ง ๊ณ์ฐ์ ์ํ ๋ณ์์ ๋๋ค.
3. ๋ฐ๋ฏธ์ง๋ฅผ ๊ณ์ฐํ๋ ํจ์ calcDamage
static void calcDamage() {
for(int n=1;n<N+1;n++) {
if(moved[n]) {
Knight knight = knights[n];
for(int i=knight.r;i<knight.r+knight.h;i++) {
for(int j=knight.c;j<knight.c+knight.w;j++) {
if(map[i][j]==1) {
knight.k-=1;
knight.damage+=1;
if(knight.k==0) { // ์์๋ ๊ธฐ์ฌ๋ ๋ ์ด์ ๋ฐ๋ฏธ์ง๋ฅผ ๊ณ์ฐํ ํ์ ์์
knight.isOut = true;
erase(n); // n๋ฒ ๊ธฐ์ฌ knight_map ๋ฐฐ์ด์์ ์ง์ฐ๊ธฐ
break;
}
}
}
if(knight.isOut) { // ์์๋ ๊ธฐ์ฌ๋ ๋ ์ด์ ๋ฐ๋ฏธ์ง๋ฅผ ๊ณ์ฐํ ํ์ ์์
break;
}
}
}
}
}
์์ง์ธ ์ฒด์ค๋ค์ ๋ํด์ ์ฒด๋ ฅ์ ๊ฐ์์ํค๊ณ , ๋ฐ๋ฏธ์ง๋ฅผ ์ฆ๊ฐ์ํต๋๋ค.
์ด๋ ๋ง์ฝ ์ฒด๋ ฅ์ด 0์ด๋๋ค๋ฉด ๊ฐ์ฒด์ ๋ณ์ isOut๋ฅผ true๋ก ์์ผ์ฃผ๊ณ ํด๋น ์ฒด์ค์์ญ์ ์ง์ฐ๋ eraseํจ์๋ฅผ ์คํํฉ๋๋ค.
๋ํ ๋ ์ด์ ๋ฐ๋ฏธ์ง๋ฅผ ๊ณ์ฐํ ํ์๊ฐ ์์ผ๋ฏ๋ก break๋ฌธ์ผ๋ก ๋ฐ๋ณต๋ฌธ์ ํ์ถํด์ค๋๋ค.
์๊ฒ๋์
- ํ๋์ ์ด์ฐจ์ ๋ฐฐ์ด์ ๋ชจ๋ ๊ฐ์ ๋ํ๋ผ ํ์๊ฐ ์์์ ์๊ฒ๋์์ต๋๋ค. ํด๋น ๋ฌธ์ ์ ๊ฒฝ์ฐ ๋ฒฝ๊ณผ ํจ์ ์ ์ ์ฅํ๋ ์ด์ฐจ์ ๋ฐฐ์ด int[][] map, ๊ธฐ์ฌ๋ค์ ์์ญ์ ์ ์ฅํ๋ 2์ฐจ์ ๋ฐฐ์ด int[][] knight_map์ ํ์ฉํ์ต๋๋ค.
- ๋ํ 2์ฐจ์ ๋ฐฐ์ด์ ๊ฐ์ฒด๋ฅผ ์ง์ ํ ๋นํ ํ์ ์์ด Knight[] knights์ ๊ฐ์ ๊ฐ์ฒด ๋ฐฐ์ด์์ ๊ฐ์ฒด๋ฅผ ๊ด๋ฆฌํ๊ณ , 2์ฐจ์ ๋ฐฐ์ด์๋ ๊ฐ์ฒด๋ค์ ์๋ณํ ์ ์๋ ์๋ณ์๋ง ๋๋ ๋ฐฉ์์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์์ ์๊ฒ๋์์ต๋๋ค.
- movable ํจ์๋ฅผ ๊ตฌํํ ๋, bfs ๋ด๋ถ์์ bfs๋ฅผ ํธ์ถํ๋ ํ์์ด์์ต๋๋ค. ์์ญ๋ณ์ ๋ํด ์ฒดํฌ๋ฅผ ์งํํ ๋ bfs๋ฅผ ํ์ฉํ ์ ์์์ ์๊ฒ๋์์ต๋๋ค.
- ์ฐ์์์ฉ์ ๊ฒฝ์ฐ ์ฌ๊ท(stack ์๋ฃ๊ตฌ์กฐ)๋ฅผ ํ์ฉํ์ฌ ๊ตฌํํ ์ ์์์ ์๊ฒ๋์์ต๋๋ค.
์ ์ฒด์ฝ๋
import java.util.*;
import java.io.*;
// ์์ญ์ ์ด๋์ํค๋ ๊ฒ
class Knight{
int r,c;
int h,w;
int k; // ์ฒด๋ ฅ
int damage;
boolean isOut;
public Knight(int r,int c,int h,int w,int k) {
this.r = r;
this.c = c;
this.h = h;
this.w = w;
this.k = k;
}
@Override
public String toString() {
return "Knight [r=" + r + ", c=" + c + ", h=" + h + ", w=" + w + ", k=" + k + ", damage=" + damage + ", isOut="
+ isOut + "]";
}
}
public class Main {
// ์
๋ ฅ ๊ฐ
static int L,N,Q;
// ์ฒด์คํ์ ๋ํ๋ด๋ ๋ฐฐ์ด
static int[][] map;
// ๊ธฐ์ฌ๋ค์ ์์น๋ฅผ ๋ํ๋ด๋ ๋ฐฐ์ด
static int[][] knight_map;
// ๊ธฐ์ฌ๋ค์ ๊ด๋ฆฌํ๋ ๋ฐฐ์ด
static Knight[] knights;
static int[] dr = {-1,0,1,0};
static int[] dc = {0,1,0,-1};
// ๋ฐ๋ฏธ์ง๋ฅผ ๊ณ์ฐํ๊ธฐ ์ํด ์ด๋ํ ๊ธฐ์ฌ๋ค์ ํ์ํ๊ธฐ ์ํ ๋ฐฐ์ด
static boolean[] moved;
static void bfs(int r,int c, Deque<int[]> q) { // ์ด๋ํ๋ ค๋ ๊ธฐ์ฌ์ ์ธ์ ํ ๊ธฐ์ฌ๋ค์ ํ์ ๋ฃ์ด์ฃผ๋ BFSํจ์
boolean[][] bfs_visited = new boolean[L][L];
Deque<int[]> bfs_q = new ArrayDeque<>();
bfs_visited[r][c] = true;
bfs_q.offer(new int[] {r,c,knight_map[r][c]});
// movable ํ ์
๋ฐ์ดํธ
q.offer(new int[] {r,c,knight_map[r][c]});
while(!bfs_q.isEmpty()) {
int[] cur = bfs_q.pollFirst();
int cr = cur[0];
int cc = cur[1];
int ck = cur[2]; // ํ์ฌ ํ์์ค์ธ ๊ธฐ์ฌ
for(int d=0;d<4;d++) {
int nr = cr + dr[d];
int nc = cc + dc[d];
if(nr<0 || nr>=L) continue;
if(nc<0 || nc>=L) continue;
if(bfs_visited[nr][nc]) continue;
if(knight_map[nr][nc]==ck) {
bfs_visited[nr][nc] = true;
bfs_q.offer(new int[] {nr,nc,ck});
// movable ํ ์
๋ฐ์ดํธ
q.offer(new int[] {nr,nc,ck});
}
}
}
}
static boolean movable(int n,int d) { // n๋ฒ ๊ธฐ์ฌ๋ฅผ d๋ฐฉํฅ์ผ๋ก ์ด๋์ํฌ ์ ์๋์ง ํ์ธ
Deque<int[]> q = new ArrayDeque<>();
Knight knight = knights[n];
for(int r=knight.r; r<knight.r+knight.h; r++) {
for(int c=knight.c; c<knight.c+knight.w; c++) {
q.offer(new int[] {r,c,n});
}
}
while(!q.isEmpty()) {
int[] cur = q.pollFirst();
int cr = cur[0];
int cc = cur[1];
int ck = cur[2]; // ํ์ฌ ํ์์ค์ธ ๊ธฐ์ฌ
int nr = cr + dr[d]; // d ๋ฐฉํฅ
int nc = cc + dc[d];
if(nr<0 || nr>=L || nc<0 || nc>=L || map[nr][nc]==2) return false; // ๋ฒฝ์ ๋ง๋๋ฉด ์ด๋ํ์ง ๋ชปํจ
if(knight_map[nr][nc]==ck) continue;
if(knight_map[nr][nc]==0) continue;
// ํ์์ค์ธ ๊ธฐ์ฌ์ ๋ค๋ฅธ ๊ธฐ์ฌ๋ฅผ ๋ง๋๋ฉด ํ์ ํด๋น ๊ธฐ์ฌ๋ค ๋ค ๋ฃ์ด์ฃผ๊ธฐ
if(knight_map[nr][nc]!=ck) {
bfs(nr,nc,q);
}
}
return true;
}
static void move(int n,int d) {
Knight knight = knights[n];
moved[n] = true;
for(int i=knight.r;i<knight.r+knight.h;i++) {
for(int j=knight.c;j<knight.c+knight.w;j++) {
int nr = i + dr[d];
int nc = j + dc[d];
// nr, nc์์น์ ๋ ๋ค๋ฅธ ๊ธฐ์ฌ๊ฐ ์์ผ๋ฉด ๊ทธ ๊ธฐ์ฌ๋ค ์ด๋์ํค๊ธฐ
if(knight_map[nr][nc]!=0 && knight_map[nr][nc]!=n) {
move(knight_map[nr][nc],d);
}
}
}
// ์ด๋์ํค๊ธฐ
for(int i=knight.r;i<knight.r+knight.h;i++) {
for(int j=knight.c;j<knight.c+knight.w;j++) {
knight_map[i][j] = 0;
}
}
for(int i=knight.r;i<knight.r+knight.h;i++) {
for(int j=knight.c;j<knight.c+knight.w;j++) {
int nr = i + dr[d];
int nc = j + dc[d];
knight_map[nr][nc] = n;
}
}
knight.r += dr[d];
knight.c += dc[d];
}
static void erase(int n) {
Knight knight = knights[n];
for(int i=knight.r;i<knight.r+knight.h;i++) {
for(int j=knight.c;j<knight.c+knight.w;j++) {
knight_map[i][j] = 0;
}
}
}
static void calcDamage() {
for(int n=1;n<N+1;n++) {
if(moved[n]) {
Knight knight = knights[n];
for(int i=knight.r;i<knight.r+knight.h;i++) {
for(int j=knight.c;j<knight.c+knight.w;j++) {
if(map[i][j]==1) {
knight.k-=1;
knight.damage+=1;
if(knight.k==0) { // ์์๋ ๊ธฐ์ฌ๋ ๋ ์ด์ ๋ฐ๋ฏธ์ง๋ฅผ ๊ณ์ฐํ ํ์ ์์
knight.isOut = true;
erase(n); // n๋ฒ ๊ธฐ์ฌ knight_map ๋ฐฐ์ด์์ ์ง์ฐ๊ธฐ
break;
}
}
}
if(knight.isOut) { // ์์๋ ๊ธฐ์ฌ๋ ๋ ์ด์ ๋ฐ๋ฏธ์ง๋ฅผ ๊ณ์ฐํ ํ์ ์์
break;
}
}
}
}
}
static void solve(int n,int d) {
if(knights[n].isOut) return;
// 1. ํด๋น ๋ฐฉํฅ์ผ๋ก ์ด๋์ด ๊ฐ๋ฅํ์ง ํ์ธํ๊ธฐ
if(!movable(n,d)) return;
// 2. ์ด๋์ํค๊ธฐ
moved = new boolean[N+1];
move(n, d);
moved[n] = false; // ๋ช
๋ น๋ฐ์ n๋ฒ ๊ธฐ์ฌ๋ ์์ง์์์ ์ ์ธ
// 3. ๋ฐ๋ฏธ์ง ๊ณ์ฐํ๊ธฐ (๋ช
๋ น์ ๋ฐ์ n๋ฒ ๊ธฐ์ฌ๋ ๋ฐ๋ฏธ์ง๋ฅผ ์
์ง ์์)
calcDamage();
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
L = Integer.parseInt(st.nextToken());
N = Integer.parseInt(st.nextToken());
Q = Integer.parseInt(st.nextToken());
map = new int[L][L];
knight_map = new int[L][L];
knights = new Knight[N+1];
for(int i=0;i<L;i++) {
st = new StringTokenizer(br.readLine());
for(int j=0;j<L;j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
for(int i=1;i<N+1;i++) {
st = new StringTokenizer(br.readLine());
int r = Integer.parseInt(st.nextToken())-1;
int c = Integer.parseInt(st.nextToken())-1;
int h = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
knights[i] = new Knight(r,c,h,w,k);
for(int a=r;a<r+h;a++) {
for(int b=c;b<c+w;b++) {
knight_map[a][b] = i;
}
}
}
for(int q=0;q<Q;q++) {
st = new StringTokenizer(br.readLine());
int i = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
// i๋ฒ ๊ธฐ์ฌ๋ฅผ d๋ฐฉํฅ์ผ๋ก ์ด๋์ํค๊ธฐ
solve(i,d);
}
int answer = 0;
for(int n=1;n<=N;n++) {
if(!knights[n].isOut) {
answer += knights[n].damage;
}
}
System.out.println(answer);
}
static void print(int[][] arr) {
for(int i=0;i<arr.length;i++) {
for(int j=0;j<arr[i].length;j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
System.out.println("-----------------");
}
}
'๐์ฝ๋ฉํ ์คํธ:CodingTest' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ํ๋ก๊ทธ๋๋จธ์ค] ๋ค๋ฆฌ๋ฅผ ์ง๋๋ ํธ๋ญ (0) | 2024.06.24 |
---|---|
[PCCP ๊ธฐ์ถ๋ฌธ์ ] 2๋ฒ / ์์ ์์ถ (0) | 2024.04.30 |
๋ฃจ๋ํ์ ๋ฐ๋(์ผ์ฑ sw์ญ๋ํ ์คํธ) (0) | 2024.04.10 |
[๋ฐฑ์ค] ์ํ ๋๋ฆฌ๊ธฐ (0) | 2024.04.09 |
[๋ฐฑ์ค] ์ฐ๊ตฌ์ 3 (์กฐํฉ, bfs) (0) | 2024.04.07 |