programmers.co.kr/learn/courses/30/lessons/60059
코딩테스트 연습 - 자물쇠와 열쇠
[[0, 0, 0], [1, 0, 0], [0, 1, 1]] [[1, 1, 1], [1, 1, 0], [1, 0, 1]] true
programmers.co.kr
카카오 3번 문제.
코딩 꼬꼬마시절(지금은 유년기 정도 되는 것 같다.) 2019년에 무턱대고 카카오 시험 보다가 좌절했던 문제이다. 강해져서 돌아왔으니 혼내주도록하자. 이래놓고 사실 내가 3시간 넘게 혼났다.
이 문제는 발상이 중요한 문제같다.
자물쇠와 키가 최소한으로 겹쳤을 때까지 커버할 수 있도록 board의 사이즈를 2 * (key 사이즈 - 1) + 자물쇠 사이즈로 두고 가능한 모든 키와 자물쇠의 조합(키 회전 + 이동)을 완전탐색하여 문제를 해결하였다.
#include <iostream>
#include <vector>
using namespace std;
typedef vector<vector<int>> vvi;
void rotate(vvi& key) {
int m = key.size();
vvi tmp(m, vector<int>(m, 0));
for (int y = 0; y < m; y++) {
for (int x = 0; x < m; x++) {
tmp[m - x - 1][y] = key[y][x];
}
}
key = tmp;
}
bool check_key(vvi& key, vvi& board, int n, int m, int s_idx) {
bool correct = 1;
//key 배열의 우하단 (m - 1, m - 1) 지점이 board의 (s_idx, s_idx)와 일치하는 경우부터
//key 벡터의 좌상단 (0, 0) 지점이 (s_idx + n - 1, s_idx + n - 1)와 일치하는 경우까지 키를 한 칸씩 이동
for (int y = s_idx - (m - 1); y < s_idx + n; y++) {
for (int x = s_idx - (m - 1); x < s_idx + n; x++) {
//insert key
for (int ky = y; ky < y + m; ky++) {
for (int kx = x; kx < x + m; kx++) {
board[ky][kx] += key[ky - y][kx - x];
}
}
//check correct
for (int y = s_idx; y < s_idx + n; y++) {
for (int x = s_idx; x < s_idx + n; x++) {
if (board[y][x] != 1) {
correct = 0;
break;
}
}
}
if (correct) return true;
//delete key
for (int ky = y; ky < y + m; ky++) {
for (int kx = x; kx < x + m; kx++) {
board[ky][kx] -= key[ky - y][kx - x];
}
}
correct = 1;
}
}
return false;
}
bool solution(vvi& key, vvi& lock) {
vvi board;
int n, m, s_idx;
n = lock.size();
m = key.size();
//lock과 1줄만 겹치도록 key를 집어 넣을 수 있도록 board의 크기를 잡아준다.
board.resize(2 * m + n - 2, vector<int>(2 * m + n - 2, 0));
s_idx = m - 1;
//insert lock
//board의 (s_idx, s_idx)에 lock의 (0, 0)이 위치
for (int y = s_idx; y < s_idx + n; y++) {
for (int x = s_idx; x < s_idx + n; x++) {
board[y][x] = lock[y - s_idx][x - s_idx];
}
}
for (int k = 0; k < 4; k++) {
rotate(key);
if (check_key(key, board, n, m, s_idx)) return true;
}
return false;
}
int main() {
vvi key;
vvi lock;
int n, m, tmp;
cin >> m >> n;
key.resize(m, vector<int>(m, 0));
lock.resize(n, vector<int>(n, 0));
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
cin >> key[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> lock[i][j];
}
}
cout << solution(key, lock) << '\n';
return 0;
}
'컴퓨터 사이언스 > 1고리즘' 카테고리의 다른 글
2019 KAKAO BLIND RECRUITMENT - 2. 실패율 (0) | 2021.01.06 |
---|---|
2019 KAKAO BLIND RECRUITMENT - 1. 오픈채팅방 (0) | 2021.01.05 |
2020 KAKAO BLIND RECRUITMENT - 2. 괄호 변환 (0) | 2021.01.05 |
2020 KAKAO BLIND RECRUITMENT - 1. 문자열 압축 (0) | 2021.01.05 |
백준 11729 : 하노이 탑 이동 순서 (0) | 2020.12.31 |