Study hard
(C++)백준 20061번: 모노미노도미노 2 본문
20061번: 모노미노도미노 2
모노미노도미노는 아래와 같이 생긴 보드에서 진행되는 게임이다. 보드는 빨간색 보드, 파란색 보드, 초록색 보드가 그림과 같이 붙어있는 형태이다. 게임에서 사용하는 좌표 (x, y)에서 x는 행,
www.acmicpc.net
[풀이]
문제에 적힌 조건들을 구현하는 문제였다.
빨간색 보드와 초록색, 파란색 보드를 모두 한 배열로 구현하지 않고, 6*4초록색보드 배열과 4*6파란색보드 배열을 따로 만들어 사용했다.
블록을 놓은 위치를 받아 먼저 초록색 보드와 파란색 보드에 블록을 옮겨줬다. 그리고 while문을 두 개 중첩하여 먼저 해이나 열이 타일로 가득 찬 경우가 없을 때까지 점수를 획득하도록 하였다.
꽉찬 행이나 열이 없으면 특별한 칸에 블록이 있는지, 있으면 몇행 또는 몇열을 차지하는지 반환하여 초록색 보드의 경우는 5-(연한칸의 블록이 있는 행 개수)행부터 그 행의 개수만큼 아래로 내려줬고, 파란색 보드는 같은 연산을 행을 열로 바꾸어서 해주었다.
※특별한 칸에 블록이 있는 경우 그 개수를 세서 모든 행이나 열에 대해 한번에 내려주지 않으면 시간초과가 난다!
#include <iostream>
#include <vector>
using namespace std;
struct Pos {
int t;
int x, y;
};
int N;
int Green[6][4];
int Blue[4][6];
vector<Pos>Block;//블록 놓은 정보
int score = 0;
void greenBlock(int t, int y) {
//1*1
if (t == 1) {
int gx = 0;
while (gx < 6) {
if (Green[gx][y] != 0)
break;
gx++;
}
gx--;
Green[gx][y] = 1;
}
//1*2
else if (t == 2) {
int gx = 0;
while (gx < 6) {
if (Green[gx][y] != 0 || Green[gx][y + 1] != 0)
break;
gx++;
}
gx--;
Green[gx][y] = 1;
Green[gx][y + 1] = 1;
}
//2*1
else if (t == 3) {
int gx = 0;
while (gx < 5) {
if (Green[gx][y] != 0 || Green[gx + 1][y] != 0)
break;
gx++;
}
gx--;
Green[gx][y] = 1;
Green[gx + 1][y] = 1;
}
}
void blueBlock(int t,int x) {
//1*1
if (t == 1) {
int gy = 0;
while (gy < 6) {
if (Blue[x][gy] != 0)
break;
gy++;
}
gy--;
Blue[x][gy] = 1;
}
//1*2
else if (t == 2) {
int gy = 0;
while (gy < 5) {
if (Blue[x][gy] != 0 || Blue[x][gy + 1] != 0)
break;
gy++;
}
gy--;
Blue[x][gy] = 1;
Blue[x][gy + 1] = 1;
}
//2*1
else if (t == 3) {
int gy = 0;
while (gy < 6) {
if (Blue[x][gy] != 0 || Blue[x + 1][gy] != 0)
break;
gy++;
}
gy--;
Blue[x][gy] = 1;
Blue[x + 1][gy] = 1;
}
}
//초록색보드에서 타일로 가득 찬 행 찾기
int greenFull() {
bool go_next = false;
for (int i = 0; i < 6; i++) {
go_next = false;
for (int j = 0; j < 4; j++) {
if (Green[i][j] == 0) {
go_next = true;
break;
}
}
if(go_next==false)
return i;
}
return -1;
}
int blueFull() {
bool go_next = false;
for (int i = 0; i < 6; i++) {
go_next = false;
for (int j = 0; j < 4; j++) {
if (Blue[j][i] == 0) {
go_next = true;
break;
}
}
if (go_next == false)
return i;
}
return -1;
}
void greenRemove(int r) {
for (int i = 0; i < 4; i++) {
Green[r][i] = 0;
}
//밑으로 내리기
for (int i = r - 1; i >= 0; i--) {
for (int j = 0; j < 4; j++) {
Green[i + 1][j] = Green[i][j];
}
}
}
void blueRemove(int c) {
for (int i = 0; i < 4; i++) {
Blue[i][c] = 0;
}
//밑으로 내리기
for (int i = c - 1; i >= 0; i--) {
for (int j = 0; j < 4; j++) {
Blue[j][i + 1] = Blue[j][i];
}
}
}
//초록색 보드의 연한 칸에 블록이 있는지
int greenSpecial() {
int cnt = 0;
for (int i = 0; i <= 1; i++) {
for (int j = 0; j < 4; j++) {
if (Green[i][j] == 1) {
cnt++;
break;
}
}
}
return cnt;
}
//파란색 보드의 연한 칸에 블록이 있는지
int blueSpecial() {
int cnt = 0;
for (int i = 0; i <= 1; i++) {
for (int j = 0; j < 4; j++) {
if (Blue[j][i] == 1) {
cnt++;
break;
}
}
}
return cnt;
}
void putBlock() {
for (int i = 0; i < N; i++) {
int t = Block[i].t;
int x = Block[i].x;
int y = Block[i].y;
//초록색 보드에 블럭 내리기
greenBlock(t, y);
//파란색 보드에 블럭 내리기
blueBlock(t, x);
while (1) {
//초록색 보드에서 행이 가득 찬 경우가 없을 때까지 점수 획득
while (1) {
int r = greenFull();
//꽉 찬 행이 없으면
if (r == -1)
break;
score++;
greenRemove(r);
}
//초록색 보드의 연한 칸에 블록이 있는지
int cnt = greenSpecial();
if (cnt == 0)
break;
for (int row = 5 - cnt; row >= 0; row--) {
for (int col = 0; col < 4; col++) {
Green[row + cnt][col] = Green[row][col];
Green[row][col] = 0;
}
}
}
//파란색 보드
while (1) {
//파란색 보드에서 행이 가득 찬 경우가 없을 때까지 점수 획득
while (1) {
int c = blueFull();
//꽉 찬 열이 없으면
if (c == -1)
break;
score++;
blueRemove(c);
}
//파란색 보드의 연한 칸에 블록이 있는지
int cnt = blueSpecial();
if (cnt == 0)
break;
for (int col = 5 - cnt; col >= 0; col--) {
for (int row = 0; row < 4; row++) {
Blue[row][col + cnt] = Blue[row][col];
Blue[row][col] = 0;
}
}
}
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(NULL);
cout.tie(NULL);
cin >> N;
int t, x, y;
for (int i = 0; i < N; i++) {
cin >> t >> x >> y;
Block.push_back({ t,x,y });
}
putBlock();
cout << score << '\n';
int block_cnt = 0;
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 4; j++) {
if (Green[i][j] == 1)
block_cnt++;
if (Blue[j][i] == 1)
block_cnt++;
}
}
cout << block_cnt << '\n';
}
'백준 > 시뮬레이션,구현' 카테고리의 다른 글
(c++)백준 21609번: 상어 중학교 (0) | 2021.09.08 |
---|---|
(c++)백준 21608번: 상어 초등학교 (0) | 2021.09.05 |
(c++)백준 15686번: 치킨 배달 (0) | 2021.04.10 |
(c++)백준 15685번: 드래곤 커브 (0) | 2021.04.09 |
(c++)백준 14891번: 톱니바퀴 (0) | 2021.04.05 |