2025-10-16 22:51:51 +09:00

82 lines
2.0 KiB
TypeScript

export {};
type tuple = [number, number, number, boolean];
class Deque <T> {
private enqueue: T[];
private dequeue: T[];
constructor() {
this.enqueue = [];
this.dequeue = [];
}
public isEmpty(): boolean {
return (this.enqueue.length === 0 && this.dequeue.length === 0);
}
public push(data: T) {
this.enqueue.push(data);
}
public popLeft(): T | undefined {
if(this.isEmpty()) {
return undefined;
}
if(this.dequeue.length === 0) {
this.enqueue.reverse();
this.dequeue = this.enqueue;
this.enqueue = [];
}
let value: T = this.dequeue.pop();
return value;
}
// 필요시 일반적인 pop과 왼쪽 삽입 매서드도 구현해서 사용하면 됩니다.
}
const input = require("fs").readFileSync(0).toString().trim().split('\n');
const [N, M] = input[0].split(' ').map(Number);
let mapData: number[][] = [];
for(let i=1; i<=N; i++) mapData.push(input[i].split('').map(Number));
let visited: boolean[][][] = Array.from({length: N}, () => Array.from({length: M}, () => [false, false]));
visited[0][0] = [true, true];
let dq = new Deque<tuple>();
dq.push([0,0,1,false]);
let result: number = -1;
const dx = [1,-1,0,0];
const dy = [0,0,1,-1];
while(!dq.isEmpty()) {
const [cx, cy, cd, breakBlock]: tuple = dq.popLeft();
if(cx === M-1 && cy === N-1) {
result = cd;
break;
}
for(let i=0; i<4; i++) {
const [nx, ny]: number[] = [cx + dx[i], cy + dy[i]];
if(ny < 0 || ny >= N || nx < 0 || nx >= M) continue;
const isWall = mapData[ny][nx] === 1;
if(isWall && breakBlock) continue;
const nextBreakBlock: boolean = breakBlock || isWall;
const blockState: number = nextBreakBlock ? 1 : 0;
if(!visited[ny][nx][blockState]) {
dq.push([nx, ny, cd+1, nextBreakBlock]);
visited[ny][nx][blockState] = true;
}
}
}
console.log(result);