반응형
https://www.acmicpc.net/problem/20061
20061번: 모노미노도미노 2
모노미노도미노는 아래와 같이 생긴 보드에서 진행되는 게임이다. 보드는 빨간색 보드, 파란색 보드, 초록색 보드가 그림과 같이 붙어있는 형태이다. 게임에서 사용하는 좌표 (x, y)에서 x는 행,
www.acmicpc.net
1. 문제설명
구조 설계를 꼼꼼히 잘 해야 해결할 수 있는 문제이다.
먼저 파란색 블록과 초록색 블록 영역은 동일하게 둘 수 있다.
들어오는 블록이 1x2거나 2x1일 때 그 블록을 서로 바꿔서 파란 영역과 초록 영역에 넣어주면 동일한 구조를 지닌다.
즉 input 블록만 회전시켜주면 초록색 영역과 파란색 영역에 동일한 시행을 하면 된다.
이를 바탕으로
나는 함수를 세가지를 만들었는데
1. 블록을 쌓는 함수,
2. 현재 쌓인 블록에서 지워질 라인이 있는지 확인하고 지우며 점수를 증가시키는 함수
3. 특별한 영역에 블록이 있는지 확인하고 그에 따라 전체 블록을 옮기는 함수.
이 세 함수를 들어오는 블록마다 파란영역과 초록 영역에 시행하면
문제를 해결할 수 있다.
주의해야할 점은
2. 현재 쌓인 블록에서 지워질 라인이 있는지 확인하고 지운 후
다시 현재 라인부터 검사해야한다.
왜냐하면 현재 라인은 이후에 검사할 라인에서 당겨왔기 때문에
검사가 안된 상태이기 때문이다.
이러한 삼성기출문제의 구현, 시뮬레이션 문제는
생각을 구조화하고 짜임새있게 해주어서 좋은 문제인 것 같다.
2.문제풀이코드 C++
#include <bits/stdc++.h>
using namespace std;
int N, point;
bool blueBoard[4][6], greenBoard[4][6];
void buildBlock(int t, int x, int y, bool board[][6]) {
if(t==1){
int ny = 0;
while(ny+1 <= 5 && board[x][ny+1] ==0 ){
ny++;
}
board[x][ny] = 1;
}
else if(t==2){
int ny = 0;
while(ny+1 <= 5 && board[x][ny+1] ==0 ){
ny++;
}
board[x][ny] = 1;
board[x][ny-1] = 1;
}
else if(t==3){
int nyFirst = 0;
while(nyFirst+1 <= 5 && board[x][nyFirst+1] ==0 ){
nyFirst++;
}
int nySecond = 0;
while(nySecond+1 <= 5 && board[x+1][nySecond+1] ==0 ){
nySecond++;
}
int ny = min(nyFirst, nySecond);
board[x][ny] = 1;
board[x+1][ny] = 1;
}
}
void checkNormalLine(bool blueBoard[][6]) {
for(int i=5; i>=2; i--){
bool flag = true;
for(int j=0; j<4; j++){
if(!blueBoard[j][i]){
flag = false;
break;
}
}
if(flag){
//Line delete;
point++;
for(int j=i; j>=1; j--){
for(int k=0; k<4; k++){
blueBoard[k][j] = blueBoard[k][j-1];
}
}
for(int k=0; k<4; k++){
blueBoard[k][0] = 0;
}
//cur Line recheck!
i++;
}
}
}
void checkSpecialLine(bool blueBoard[][6]) {
bool flag0 = false;
bool flag1 = false;
for(int i=0; i<4; i++){
if(blueBoard[i][0]){
flag0 = true;
}
if(blueBoard[i][1]){
flag1 = true;
}
}
if(flag0&&flag1){
//2칸
for(int i=5; i>=2; i--){
for(int j=0; j<4; j++){
blueBoard[j][i] = blueBoard[j][i-2];
}
}
for(int k=0; k<4; k++){
blueBoard[k][0] = 0;
blueBoard[k][1] = 0;
}
}
else if(flag1){ //1칸
for(int i=5; i>=1; i--){
for(int j=0; j<4; j++){
blueBoard[j][i] = blueBoard[j][i-1];
}
}
for(int k=0; k<4; k++){
blueBoard[k][0] = 0;
}
}
}
int getBlockNum() {
int blocks = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 6; j++) {
if (blueBoard[i][j]) blocks++;
if (greenBoard[i][j]) blocks++;
}
}
return blocks;
}
void print(){
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 6; j++) {
cout << blueBoard[i][j] << ' ';
}
cout << '\n';
}
cout << "-----------------------\n";
for(int i=0; i<6; i++){
for(int j=0; j<4; j++){
cout << greenBoard[j][i] << ' ';
}
cout << '\n';
}
cout <<'\n';
cout << "-----------------------\n";
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N;
for (int i = 0; i < N; i++) {
int t, x, y;
cin >> t >> x >> y;
buildBlock(t, x, y, blueBoard);
//90' 회전
if (t == 2) t = 3;
else if (t == 3) t = 2;
buildBlock(t, y, x, greenBoard);
checkNormalLine(blueBoard);
checkNormalLine(greenBoard);
checkSpecialLine(blueBoard);
checkSpecialLine(greenBoard);
// print();
}
cout << point << '\n';
cout << getBlockNum() << '\n';
}
반응형
'Algorithm > problem' 카테고리의 다른 글
백준 19237번 : 어른 상어 - 구현, 시뮬레이션 C++ (0) | 2022.07.22 |
---|---|
백준 19236번 : 청소년 상어 - 백트래킹 Cpp (0) | 2022.07.18 |
백준 17825번 : 주사위 윷놀이 - 백트래킹 (0) | 2022.07.14 |
백준 17822번 : 원판 돌리기 - 구현, 시뮬레이션 C++ (0) | 2022.07.13 |
백준 17837번 : 새로운 게임 2 - 시뮬레이션 Cpp (0) | 2022.07.12 |