티스토리 뷰
1. 문제 링크
2. 문제 개요 및 풀이
이 글의 내용과 아주 비슷하다.
차이점은 블록이 한 줄 가득 차면 지워지게 되는데, 그때 위에 쌓여있던 블록이 경계를 내려갈 때까지 쭉 내려가느냐(중력 받는 것처럼 우수수수), 아니면 그냥 실제 진짜 테트리스처럼 한 줄만 딱 내려가느냐 그 차이다.
그래서 19235번의 코드를 재활용해서 지저분하긴 하다.
다른 부분의 풀이는 위의 링크를 눌러서 보시면 될 것 같습니다.
19235문제와 다른점을 코드로 나타내자면,
void pull_right(int x)
{
for (int j = x; j >= 4; --j)
for (int i = 0; i < 4; ++i)
row[i][j] = row[i][j - 1];
return;
}
void pull_down(int y)
{
for (int i = y; i >= 4; --i)
for (int j = 0; j < 4; ++j)
col[i][j] = col[i - 1][j];
return;
}
이 두개의 함수를 추가해준 것입니다.(모노미노도미노 와 이 부분이 다른 것.)
기존의 블록이 깨질경우 멈춰야 할 때까지 우수수수 내려가는 게 아닌, 위의 반복문처럼 한 줄이 삭제될 경우 한 줄씩만 내려오면 되기 때문에, 추가했습니다. 위의 코드는 딱 한 줄만 끌어내립니다.
그래서 기존의 문제에서는 한줄이 삭제되고 또 떨어지는 것에 의해서 삭제될 확률이 있기 때문에 그 부분을 처리해주어야 했지만, 이번 문제에서는 그런 경우가 없기 때문에 그에 따라 main함수도 while반복문을 쓰지 않고 풀 수 있었습니다.
2번에 링크로 걸어놨던 문제가 더 어렵고 이번 문제가 더 쉬운데다가 약간 포함되는 형식의 문제이기 때문에, 풀이는 2번의 링크를 타고 보셔도 될 것 같습니다.
3. 코드
밑의 코드는 정답이긴하나, 모노미노도미노 1의 코드를 재활용한 거라 코드를 보실 거면 모노미노도미노1의 코드를 보는 것을 추천드립니다.
#include <cstdio>
using namespace std;
int row[4][10], col[10][4]; //map
int n, ans, score;
void put_block(int y, int x , int type) //y : row, x : col
{
if (type == 1){
// 1*1 block
row[y][x] = col[y][x] = 1;
}
else if (type == 2) {
// 1*2 block
row[y][x] = row[y][x + 1] = 1;
col[y][x] = 2; col[y][x + 1] = -2;
}
else{
// 2*1block
row[y][x] = 3; row[y + 1][x] = -3;
col[y][x] = col[y + 1][x] = 1;
}
}
void move_right(int y, int x)
{
if (row[y][x] == 1){
if (x < 9)
if (row[y][x + 1] == 0) {
row[y][x] = 0;
row[y][x + 1] = 1;
move_right(y, x + 1);
}
}
else if (row[y][x] == 3){
if (x < 9) {
if (row[y][x + 1] == 0 && row[y + 1][x + 1] == 0)
{
row[y][x] = row[y + 1][x] = 0;
row[y][x + 1] = 3; row[y + 1][x + 1] = -3;
move_right(y, x + 1);
}
}
}
return;
}
void push_right(int start, int end)
{
//[start, end]
for (int j = end; j >= start; --j)
for (int i = 0; i < 4; ++i)
if (row[i][j] != 0)
move_right(i, j);
return;
}
void move_down(int y, int x)
{
if (col[y][x] == 1){
if (y < 9)
if (col[y + 1][x] == 0){
col[y][x] = 0;
col[y + 1][x] = 1;
move_down(y + 1, x);
}
}
else if(col[y][x] == 2){
if (y < 9)
if (col[y + 1][x] == 0 && col[y + 1][x + 1] == 0){
col[y][x] = col[y][x + 1] = 0;
col[y + 1][x] = 2; col[y + 1][x + 1] = -2;
move_down(y + 1, x);
}
}
return;
}
void push_down(int start, int end)
{
//[start, end]
for (int i = end; i >= start; --i)
for (int j = 0; j < 4; ++j)
if (col[i][j] != 0)
move_down(i, j);
return;
}
bool isfull_row(int y) {
//if a row is full, then return true.
for (int j = 0; j < 4; ++j)
if (col[y][j] == 0)
return false;
return true;
}
bool isfull_col(int x) {
for (int i = 0; i < 4; ++i)
if (row[i][x] == 0)
return false;
return true;
}
void erase_row(int y)
{
for (int j = 0; j < 4; ++j)
col[y][j] = 0;
return;
}
void pull_down(int y)
{
for (int i = y; i >= 4; --i)
for (int j = 0; j < 4; ++j)
col[i][j] = col[i - 1][j];
return;
}
void erase_col(int x)
{
for (int i = 0; i < 4; ++i)
row[i][x] = 0;
return;
}
void pull_right(int x)
{
for (int j = x; j >= 4; --j)
for (int i = 0; i < 4; ++i)
row[i][j] = row[i][j - 1];
return;
}
bool warning_erea_row(int y)
{
for (int j = 0; j < 4; ++j)
if (col[y][j] != 0)
return true;
return false;
}
bool warning_erea_col(int x)
{
for (int i = 0; i < 4; ++i)
if (row[i][x] != 0)
return true;
return false;
}
int main()
{
scanf("%d", &n);
while (n--)
{
//t, row(x), col(y) -> t, row(y), col(x)
int t, x, y;
scanf("%d %d %d", &t, &y, &x);
//construct block
//push initial block
put_block(y, x, t);
push_right(0, 3);
push_down(0, 3);
//row first
for (int j = 6; j <= 9; ++j) {
if (isfull_col(j)) {
++score;
erase_col(j);
pull_right(j);
}
}
int cnt = 9;
if (warning_erea_col(5))
erase_col(cnt--);
if (warning_erea_col(4))
erase_col(cnt--);
//if (cnt != 9)
//push_right(4, 8);
if (cnt == 8)
pull_right(9);
if (cnt == 7) {
pull_right(8);
pull_right(9);
}
//col
for (int i = 6; i <= 9; ++i) {
if (isfull_row(i)) {
++score;
erase_row(i);
pull_down(i);
}
}
cnt = 9;
if (warning_erea_row(5))
erase_row(cnt--);
if (warning_erea_row(4))
erase_row(cnt--);
//if (cnt != 9)
//push_down(4, 8);
if (cnt == 8)
pull_down(9);
if (cnt == 7) {
pull_down(8);
pull_down(9);
}
}
for (int i = 6; i <= 9; ++i)
for (int j = 0; j < 4; ++j)
{
if (col[i][j] != 0)
++ans;
if (row[j][i] != 0)
++ans;
}
printf("%d\n%d",score, ans);
return 0;
}
4. 결과
'알고리즘 > 삼성 SW테스트' 카테고리의 다른 글
boj, 백준) 20056. 마법사 상어와 파이어볼 (C / C++) (4) | 2021.01.22 |
---|---|
boj, 백준) 20055. 컨베이어 벨트 위의 로봇 ( C / C++ ) (0) | 2020.10.25 |
boj, 백준) 19235. 모노미노도미노 ( C / C++ ) (0) | 2020.10.23 |
boj, 백준) 19238. 스타트택시 ( C / C++ ) (0) | 2020.10.11 |
boj, 백준) 19237. 어른상어 ( C / C++) (13) | 2020.07.31 |
댓글