[프로그래머스] 2020 KAKAO BLIND RECRUITMENT 기둥과 보 설치
실제 시험때 제가 썼던 전략은 다음과 같습니다.
설치/삭제하려는 위치를 기준으로 주변의 상황을 둘러보고 결정해야 하기 때문에 현재 위치를 기준으로 시계방향의 위치를 배열로 만들어둡니다. 그 뒤 isPillar, isBeam 메서드를 활용해서 설치/삭제 여부를 결정합니다.
자세한 내용은 주석으로 봐주세요~!
import java.util.Arrays;
class Loc{
int x;
int y;
Loc(int x, int y){
this.x = x;
this.y = y;
}
}
class Solution {
static int[][] map;
static int size;
public int[][] solution(int n, int[][] build_frame) {
size = n+1;
map = new int[n+1][n+1]; // row, col 위치에 설치된 기둥/보 현황을 기록할 이차배열
// 0 : 아무것도 설치되지 않음
// 1 : 기둥만 설치
// 2 : 보만 설치
// 3 : 기둥과 보 모두 설치되어있음
int acts = build_frame.length;
int pillarsAndBeams = 0; // 기둥과 보의 수를 기록할 변수
for(int act = 0 ; act < acts ; act++) {
// 순서대로 문제에 제시된 x,y,a,b 입니다
int col = build_frame[act][0];
int row = build_frame[act][1];
int obj = build_frame[act][2];
int set = build_frame[act][3];
// 현재 위치를 기준으로 시계방향의 좌표를 저장할 배열입니다.
// 0시는 현재 위치를 기록하고, 순서대로 1시, 3시, 5시, 6시, 7시, 9시, 11시, 12시 방향입니다.
Loc[] loc = new Loc[13];
loc[0] = new Loc(row, col);
loc[1] = new Loc(row+1, col+1);
loc[3] = new Loc(row, col+1);
loc[5] = new Loc(row-1, col+1);
loc[6] = new Loc(row-1, col);
loc[7] = new Loc(row-1, col-1);
loc[9] = new Loc(row, col-1);
loc[11] = new Loc(row+1, col-1);
loc[12] = new Loc(row+1, col);
if(set == 0) { // 삭제
if(obj == 0) { // 기둥
// 기둥이 삭제 되기 위한 조건
// 유일하게 이 기둥을 의지하고 있는 보나 기둥이 하나도 없어야 함
if(isPillar(loc[12])) {
if(!(isBeam(loc[11]) || isBeam(loc[12]))){
continue;
}
}
if(isBeam(loc[11])) {
if(!( isPillar(loc[9]) || (isBeam(loc[12]) && isBeam(new Loc(row+1, col-2))))){
continue;
}
}
if(isBeam(loc[12])) {
if(!(isPillar(loc[3]) || (isBeam(loc[11]) && isBeam(loc[1])))) {
continue;
}
}
map[row][col] -= 1;
pillarsAndBeams--;
}else { // 보
// 보가 삭제되기 위한 조건
// 유일하게 이 보를 의지하고 있는 보나 기둥이 하나도 없어야 함
if(isPillar(loc[0])) {
if(!(isBeam(loc[9]) || isPillar(loc[6])) ){
continue;
}
}
if(isPillar(loc[3])){
if(!(isBeam(loc[3]) || isPillar(loc[5]))) {
continue;
}
}
if(isBeam(loc[9])){
if(!(isPillar(loc[7]) || isPillar(loc[6]))) {
continue;
}
}
if(isBeam(loc[3])){
if(!(isPillar(loc[5]) || isPillar(new Loc(row-1, col+2)))) {
continue;
}
}
map[row][col] -= 2;
pillarsAndBeams--;
}
}else { // 설치
if(obj == 0) { // 기둥
// 기둥이 설치되기 위한 조건
// 설치되는 장소양쪽중 하나에 보가 있거나 아래에 기둥이 있어야함
// 혹은 설치장소가 바닥이어야 함
if( row == 0 || isPillar(loc[6]) || isBeam(loc[9]) || isBeam(loc[0])){
map[row][col] += 1;
pillarsAndBeams++;
}
}else { // 보
// 보가 설치되기 위한 조건
// 설치되는 장소 양끝 중 하나에 기둥이 있거나 양끝에 보가 있어야 함
if(isPillar(loc[6]) || isPillar(loc[5]) || (isBeam(loc[9]) && isBeam(loc[3]))) {
map[row][col] += 2;
pillarsAndBeams++;
}
}
}
}
// 답을 옮겨봅시다
int[][] answer = new int[pillarsAndBeams][3];
int idx = 0;
for(int col = 0 ; col < n+1 ; col++) { // col 오름차순
for(int row = 0 ; row < n+1 ; row++) { // col이 같다면 row 오름차순
int val = map[row][col];
if(val == 0) continue; // 아무것도 설치되지 않음 -> 통과
answer[idx][0] = col;
answer[idx][1] = row;
if(val == 1) { //
answer[idx][2] = 0; // 기둥이 설치됨
}else if(val == 2) {
answer[idx][2] = 1; // 보가 설치됨
}else if(val == 3) { // 둘다 설치되어있는 경우는
answer[idx++][2] = 0; // 기둥을 먼저 저장
answer[idx][0] = col;
answer[idx][1] = row;
answer[idx][2] = 1; // 보 저장
}
idx++;
}
}
return answer;
}
// loc에 기둥이 설치되어있는지 여부를 반환하는 메서드
static boolean isPillar(Loc loc) {
int x = loc.x;
int y = loc.y;
if(x < 0 || x >= size || y < 0 || y >= size || !(map[x][y] == 1 || map[x][y] == 3)) {
return false;
}
return true;
}
// loc에 보가 설치되어 있는지 여부를 반환하는 메서드
static boolean isBeam(Loc loc) {
int x = loc.x;
int y = loc.y;
if(x < 0 || x >= size || y < 0 || y >= size || !(map[x][y] == 2 || map[x][y] == 3)) {
return false;
}
return true;
}
}
Comments