1. 문제
2. 접근방법
테트리스 변화 버젼? 같은 느낌의 문제
나는 초록색이랑 파란색이랑 함수 따로 만들기 싫어서 파란색 영역을 90도 돌려졌다 생각하고 풀었다.
이런 느낌으로 초록색에 떨어뜨릴 때는 정상좌표에서 떨어지고
파란색으로 떨어뜨릴 때는 x좌표랑 y좌표를 서로 바꾸고
모양이 가로면 세로로 세로면 가로로 바꿔서 떨어 뜨리면 똑같이 떨어뜨릴 수 있다.
1. 블록을 떨어뜨리고
2. 한줄이 찼으면 한줄을 삭제
3. 빈칸 채워 넣기 -> 한 줄이 다시 찼으면 다시 2번
4. 특별구역에 블록 있으면 처리
5. 빈칸 채워 넣기
의 순으로 시뮬이 돌아간다.
여기서 빈칸을 채워 넣을 때
다른 모양들은 아래 빈칸이 있으면 무조건 바닥으로 떨어뜨리면 되지만
가로 모양 블록은 떨어질 때 두 블록 모두에서 검사가 필요하다.
그래서 가로모양만 예외로 처리하면 되므로
다른 블록은 모두 1로 집어넣고 가로모양 블록만 왼쪽은 2 오른쪽은 3으로 map에 저장했다.
이 후 빈칸이 생겨 빈칸을 채울 때 가로 모양의 블록만 왼쪽 오른쪽 모두 검사하며 떨어지게 만들었다.
3. 자바 코드
package Platinum;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class P19235모노미노도미노 {
// 모양 3개
// 빨간거에 두면아래 오른쪽 이동
// 한줄 채우면 사라지고 1점획득
// 특수칸 들어가면 그 행수만큼 아래 행 삭제
static int bluemap[][] = new int[6][4];
static int greenmap[][] = new int[6][4];
static int score;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int N = Integer.parseInt(br.readLine());
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
int t = Integer.parseInt(st.nextToken()); // 1 : 1*1 , 2 : 1*2 , 3 : 2*1
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
boolean isblue = true;
for (int k = 0; k < 2; k++) {
dropblock(t, x, y, isblue);
boolean pung = true;
while(pung) {
pung = oneline(isblue);
fillblank(isblue);
}
specialline(isblue);
fillblank(isblue);
isblue = false;
}
}
int cnt = count(true) + count(false);
System.out.println(score);
System.out.println(cnt);
}
static void dropblock(int t, int x, int y, boolean isblue) {
int map[][];
if (isblue) {
map = bluemap;
x = y ^ x ^ (y = x);
t = t == 1 ? 1 : t == 2 ? 3 : 2;
} else
map = greenmap;
int row = 0;
for (int i = 2; i <= 6; i++) {
if (i == 6) {
row = i - 1;
break;
}
if (map[i][y] != 0) {
row = i - 1;
break;
}
if (t == 2 && map[i][y + 1] != 0) {
row = i - 1;
break;
}
}
map[row][y] = 1;
if (t == 2) {
map[row][y] = 2;
map[row][y + 1] = 3;
} else if (t == 3)
map[row - 1][y] = 1;
}
static void dropblank(int t, int x, int y, boolean isblue) {
int[][] map = isblue ? bluemap : greenmap;
int row = 0;
for (int i = x + 1; i <= 6; i++) {
if (i == 6) {
row = i - 1;
break;
}
if (map[i][y] != 0 ) {
row = i - 1;
break;
}
if (t == 2 && map[i][y + 1] != 0 ) {
row = i - 1;
break;
}
}
map[row][y] = 1;
if (t == 2) {
map[row][y] = 2;
map[row][y + 1] = 3;
}
}
static void fillblank(boolean isblue) {
int[][] map = isblue ? bluemap : greenmap;
for (int i = 4; i >= 0; i--) {
for (int j = 0; j < 4; j++) {
if (map[i][j] == 1 && map[i + 1][j] == 0) {
map[i][j] = 0;
dropblank(1,i,j,isblue);
}
if (map[i][j] == 2 && map[i + 1][j+1] == 0 && map[i + 1][j] == 0) {
map[i][j] = 0;
map[i][j+1] = 0;
dropblank(2,i,j,isblue);
}
}
}
}
static boolean oneline(boolean isblue) {
int[][] map = isblue ? bluemap : greenmap;
boolean pung = false;
for (int i = 2; i < 6; i++) {
boolean fill = true;
for (int j = 0; j < 4; j++) {
if (map[i][j] == 0) {
fill = false;
break;
}
}
if (fill) {
score++;
for (int j = 0; j < 4; j++)
map[i][j] = 0;
pung = true;
}
}
return pung;
}
static void specialline(boolean isblue) {
int[][] map = isblue ? bluemap : greenmap;
int dline = 0;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 4; j++) {
if (map[i][j] == 1 || map[i][j] == 2) {
dline++;
break;
}
}
}
for (int i = 5; i > 5 - dline; i--) {
for (int j = 0; j < 4; j++)
map[i][j] = 0;
}
}
static int count(boolean isblue) {
int[][] map = isblue ? bluemap : greenmap;
int cnt = 0;
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 4; j++) {
if (map[i][j] == 1 || map[i][j] == 2 || map[i][j] == 3)
cnt++;
}
}
return cnt;
}
}
4. 마치며
내 첫 플레 문제
조금 더 간단한 모노미노도미노2를 먼저 풀고 푼거라
코드를 조금만 수정하면 돼서 시간이 많이 걸리진 않았다.
'알고리즘 문제풀이 > 백준' 카테고리의 다른 글
[백준] 20159 동작 그만 밑장 빼기냐 (0) | 2020.12.03 |
---|---|
[백준] 17406 배열 돌리기4 (0) | 2020.12.02 |
[백준] 15685 드래곤 커브 (0) | 2020.11.06 |
[백준] 14698 전생했더니 슬라임 연구자였던 건에 대하여 (Hard) (0) | 2020.11.05 |
[백준] 2239 스도쿠 (0) | 2020.11.04 |