Algorithm/삼성 SW 역량 테스트 기출 문제
[Baekjoon][20061] 모노미노도미노 2
어발
2022. 2. 28. 14:25
출처 - 백준사이트
나의 풀이
블록 입력시 초록색맵과 파란색 맵에 알맞은 위치에 블록이 생성하게 한뒤, 동일한 블록이동 함수를 사용하여 구현.
블록이동 함수는 수평도미노 이동함수, 단일 혹은 수직도미노 이동함수 2개로 구현하였다.
주의해야할 반례,
0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 0
1 1 0 1 -> 0 0 1 0 옆의 예시처럼 모든 행이 1인 구간이 먼저 삭제 됨을 유의.
1 0 1 0 1 0 1 0
0 0 1 0 0 0 1 0
0 1 1 1 0 1 1 1
해당 반례 및 답.
8
3 1 0
3 0 1
1 2 1
1 0 0
3 2 1
3 0 1
1 3 1 answer : 1
2 2 1 14
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int N, score, remain;
int GreenMap[10][4];
int BlueMap[10][4];
void deleteMap(int (*map)[4], int y) {
for (int i = y ; i > 4; i--)
memcpy(map[i], map[i-1], sizeof(map[0]));
memset(map[4], 0, sizeof(map[0]));
}
void moving_vertical(vector<pair<int,int>> &v, int (*map)[4]) {
int py1 = -1, px1 = -1, py2 = -1, px2 = -1;
int ny1 = -1, nx1 = -1, ny2 = -1, nx2 = -1;
if (v.size() == 2) {
if (v[0].first > v[1].first) {
py1 = v[0].first, px1 = v[0].second;
py2 = v[1].first, px2 = v[1].second;
}
else {
py1 = v[1].first, px1 = v[1].second;
py2 = v[0].first, px2 = v[0].second;
}
}
else
py1 = v[0].first, px1 = v[0].second;
while (1) {
ny1 = py1 + 1, nx1 = px1;
if (py2 != -1 && px2 != -1)
ny2 = py2 + 1, nx2 = px2;
if (ny1 < 10) {
if (map[ny1][nx1] == 0) {
map[py1][px1] = 0;
map[ny1][nx1] = 1;
py1 = ny1, px1 = nx1;
if (py2 != -1 && px2 != -1) {
map[py2][px2] = 0;
map[ny2][nx2] = 1;
py2 = ny2, px2 = nx2;
}
}
else
break;
}
else
break;
}
if (map[py1][0] && map[py1][1] && map[py1][2] && map[py1][3]) {
score++;
deleteMap(map, py1);
if (py2 != -1 && px2 != -1) {
py2 = py1, px2 = px1;
if (map[py2][0] && map[py2][1] && map[py2][2] && map[py2][3]) {
score++;
deleteMap(map, py2);
}
}
}
if (map[py2][0] && map[py2][1] && map[py2][2] && map[py2][3]) {
score++;
deleteMap(map, py2);
}
if (map[5][0] || map[5][1] || map[5][2] || map[5][3]) // 연한분에 속했을때
deleteMap(map, 9);
if (map[5][0] || map[5][1] || map[5][2] || map[5][3]) // 연한분에 속했을때
deleteMap(map, 9);
}
void moving_horizon(vector<pair<int,int>> &v, int (*map)[4]) {
int py1 = -1, px1 = -1, py2 = -1, px2 = -1;
int ny1 = -1, nx1 = -1, ny2 = -1, nx2 = -1;
if (v[0].first > v[1].first) {
py1 = v[0].first, px1 = v[0].second;
py2 = v[1].first, px2 = v[1].second;
}
else {
py1 = v[1].first, px1 = v[1].second;
py2 = v[0].first, px2 = v[0].second;
}
while (1) {
ny1 = py1 + 1, nx1 = px1;
ny2 = py2 + 1, nx2 = px2;
if (ny1 < 10 && ny2 < 10) {
if (map[ny1][nx1] == 0 && map[ny2][nx2] == 0) {
map[py1][px1] = 0, map[py2][px2] = 0;
map[ny1][nx1] = 1, map[ny2][nx2] = 1;
py1 = ny1, px1 = nx1;
py2 = ny2, px2 = nx2;
}
else
break;
}
else
break;
}
if (map[py1][0] && map[py1][1] && map[py1][2] && map[py1][3]) {
score++;
deleteMap(map, py1);
}
if (map[5][0] || map[5][1] || map[5][2] || map[5][2]) // 연한분에 속했을때
deleteMap(map, 9);
}
void doBlue(int t, int x, int y) {
BlueMap[y][3-x] = 1;
vector<pair<int,int>> block;
block.push_back({y, 3-x});
if (t == 1)
moving_vertical(block, BlueMap);
else if (t == 2) {
BlueMap[y+1][3-x] = 1;
block.push_back({y+1, 3-x});
moving_vertical(block, BlueMap);
}
else if (t == 3) {
BlueMap[y][3-x-1] = 1;
block.push_back({y, 3-x-1});
moving_horizon(block, BlueMap);
}
}
void doGreen(int t, int x, int y) {
GreenMap[x][y] = 1;
vector<pair<int,int>> block;
block.push_back({x, y});
if (t == 1)
moving_vertical(block, GreenMap);
else if (t == 2) {
GreenMap[x][y+1] = 1;
block.push_back({x, y+1});
moving_horizon(block, GreenMap);
}
else if (t == 3) {
GreenMap[x+1][y] = 1;
block.push_back({x+1, y});
moving_vertical(block, GreenMap);
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> N;
for (int i = 0 ; i < N ; i++) {
int t, x, y;
cin >> t >> x >> y;
doGreen(t,x,y);
doBlue(t,x,y);
}
cout << score << endl;
for (int y = 6 ; y < 10 ; y++) {
for (int x = 0 ; x < 4 ; x++) {
if (GreenMap[y][x] == 1)
remain++;
if (BlueMap[y][x] == 1)
remain++;
}
}
cout << remain << endl;
return 0;
}
728x90