제민
19235 모노미노도미노 본문
https://www.acmicpc.net/problem/19235
19235번: 모노미노도미노
모노미노도미노는 아래와 같이 생긴 보드에서 진행되는 게임이다. 보드는 빨간색 보드, 파란색 보드, 초록색 보드가 그림과 같이 붙어있는 형태이다. 게임에서 사용하는 좌표 (x, y)에서 x는 행,
www.acmicpc.net
역대급으로 힘들었던 시뮬레이션 문제이다. 아이디어는 다 떠올렸는데 부족한 구현력으로 구현에 실패했다.
https://velog.io/@front/백준-모노미노도미노-19235
백준 - 모노미노도미노 (19235)
문제 링크특별한 알고리즘은 요구하지 않고오로지 구현력으로 승부를 보는 문제입니다.이런 빡구현 유형은 문제를 단순화하는 부분부터 시작합니다.문제에서는 초록색 보드와 파란색 보드 둘
velog.io
블럭 배치까지는 잘 했는데 삭제 부분이 너무 까다로웠다. 저 글을 보면서 나도 이런 복잡한 구현 문제는 함수형 프로그래밍을 사용해 풀어야겠다고 생각했다.
#include <bits/stdc++.h>
using namespace std;
#define ROW 10
#define COL 4
int n,score;
int board[ROW][COL][2]; //빨-초 그리고 빨-파 두 부분으로 구분시킴
int blockTypeY[3]={0,0,1};
int blockTypeX[3]={0,1,0};
void printBoard(){
cout<<"Green\n";
for(int i=0;i<ROW;i++){
for(int j=0;j<COL;j++){
cout<<board[i][j][0]<<' ';
}cout<<'\n';
}
cout<<"Blue\n";
for(int i=0;i<ROW;i++){
for(int j=COL-1;j>=0;j--){
cout<<board[i][j][1]<<' ';
}cout<<'\n';
}
}
void dropBlock(int color, int y1, int x1, int y2, int x2, int type){
while(y1<ROW && y2<ROW && !board[y1][x1][color] && !board[y2][x2][color]){
y1++; y2++;
} board[y1-1][x1][color] = board[y2-1][x2][color] = type;
}
void deleteRow(int color, int row){
for(int c=0;c<COL;c++) board[row][c][color]=0;
}
void downBlock(int color, int row){
for(int r=row;r>=4;r--){ //아래에서 위로 올라감
for(int c=0;c<COL;c++){
if(board[r][c][color]==1){ //1x1(type 1) or 2x1(type 3)은 그냥 내려가면 됨
board[r][c][color]=0;
dropBlock(color,r,c,r,c,1);
}
if(board[r][c][color]==2){ //가로로 긴 블럭(type 2)은 따로 처리
board[r][c][color]=board[r][c+1][color]=0;
dropBlock(color,r,c,r,c+1,2);
}
}
}
}
void deleteRowUntilAvailable(int color){
while(1){
int mxDeletedRow=-1;
for(int r=4;r<ROW;r++){ //위에서부터 내려가면서 다 차있는지 확인
bool isDelete = true;
for(int c=0;c<COL;c++){
if(board[r][c][color]==0){ //돌다가 그 줄에 0이 하나라도 있으면 continue
isDelete=false; break;
}
}
if(!isDelete) continue;
//다 차있다면
deleteRow(color,r);
score++;
mxDeletedRow=r;
}
if(mxDeletedRow==-1) break;
downBlock(color,mxDeletedRow-1); //지운 Row의 위쪽 Row를 인수로 넣음
}
}
void handleSoftCell(int color){
int count=0;
for(int r=5;r>=4;r--){
for(int c=0;c<COL;c++){
if(board[r][c][color]>0){
count++; break;
}
}
if(count==0) return;
}
for(int r=ROW-1;r>ROW-1-count;r--){
deleteRow(color,r);
}
downBlock(color,ROW-count-1); //블럭을 전체적으로 내림
}
int getCellCount(int color){
int ret=0;
for(int r=6;r<ROW;r++)
for(int c=0;c<COL;c++)
if(board[r][c][color]>0) ret++;
return ret;
}
int main() {
ios::sync_with_stdio(0);
cin>>n;
while(n--){
int t,y1,x1; cin>>t>>y1>>x1;
int y2 = y1 + blockTypeY[t-1];
int x2 = x1 + blockTypeX[t-1];
//삼항 연산자로 2 type (Green 기준 hw 1:2)를 2로, 나머진 1로 변환
dropBlock(0, y1, x1, y2, x2, t==3?1:t);
deleteRowUntilAvailable(0);
handleSoftCell(0); //연한칸 처리
//파랑 부분은 초록을 y=-x를 기준으로 대칭시킨 것
//삼항 연산자로 3 type (Blue 기준 hw 1:2) 을 2로 변환
dropBlock(1, x1, y1, x2, y2, t==3?2:1);
deleteRowUntilAvailable(1);
handleSoftCell(1);
//printBoard(); cout<<'\n';
}
cout<<score<<'\n'<<(getCellCount(0)+getCellCount(1));
return 0;
}
'코테연습일지 > 구현 (시뮬레이션)' 카테고리의 다른 글
17406 배열 돌리기 4 (4) | 2024.03.05 |
---|---|
17825 주사위 윷놀이 (0) | 2024.03.04 |
20061 모노미노도미노 2 (0) | 2024.03.02 |
19236 청소년 상어 (0) | 2024.02.24 |
17140 이차원 배열과 연산 (0) | 2024.02.24 |