알고리즘/프로그래머스(C++)

[프로그래머스/알고리즘]블록게임

chaibin 2019. 3. 9. 14:53

블록게임






문제를 너무 막 풀어서 코드가 너무 길어버렸네요;;


가로 2X3 세로 3X2 가능한 블록만 모여나서 하나하나 비교하는 형식으로 풀었습니다.


비교했는데 비교한 전부 비교가 가능하면 지워나가는 형식으로 했습니다.


possible배열은 가장 위에 어떤 블록이 있는가를 설정해서


벽이 있으나 해당 줄에 2개가 있을 경우 qqq(이름 뭘로 지을지 몰라서 막지음)변수에 저장, qqq가 2개 있을 경우 검은 블록을 안떨어뜨려도 된다고 코드를 짰습니다. 


소스코드

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
bool checkgaro(vector<int> &possible, vector<vector<int>> &board, int i, int j, int &answer);
bool checksero(vector<int> &possible, vector<vector<int>> &board, int i, int j, int &answer);
void checkline(vector<int> &possible, vector<vector<int>> board);
	
vector<vector<vector<int>>> garo = {
	{{1,0,0},
	{1,1,1}},

	{{0,1,0},
	{1,1,1}},

	{{0,0,1},
	{1,1,1}}
};

vector<vector<vector<int>>> sero = {
	{{1,0},
	{1,0},
	{1,1}},

	{{0,1},
	{0,1},
	{1,1}}
};

int solution(vector<vector<int>> board) {
	int answer = 0;
	vector<int> possible(board[0].size());
	checkline(possible, board);
	for (int i = 0; i < board.size()-1; i++) {
		for (int j = 0; j < board[0].size() - 1; j++) {
			if (i< board.size() - 2) //세로 불가능할때
				if (checksero(possible, board, i, j,answer))
					j = -1;
			if (j < board[0].size() - 2)  //가로 불가능할 때
				if (checkgaro(possible, board, i, j,answer))
					j = -1;
		}
	}
	return answer;
}

void checkline(vector<int> &possible, vector<vector<int>> board) {
	for (int a = 0; a < board[0].size(); a++) {
		if (possible[a] != 0) continue;
		for (int i = 0; i<board.size(); i++) {
			if (possible[a]==0 && (board[i][a]!=0)) {
				possible[a] = board[i][a];
			}
		}
	}
}

bool checkgaro(vector<int> &possible, vector<vector<int>> &board, int i, int j,int &answer) {
	int block = 0;
	for (int a = 0; a < garo.size(); a++) {
		int temp = 0;		//일치율
		for (int c = 0, j_ = j; c < 3; c++, j_++) {
			int qqq = 0;
			for (int b = 0, i_ = i; b < 2; b++, i_++) {
				if (garo[a][b][c] == board[i_][j_] || (garo[a][b][c]>0 && board[i_][j_]>0)) {
					if (garo[a][b][c] == 0) {
						temp++;
						continue;
					}
					if (block == 0 || board[i_][j_] == block) {
						block = board[i_][j_];
						if (possible[j_] != board[i_][j_]) {
							qqq++;          //위에 벽에 막혀있어도 그 칸이 있어도 허용하게함
							continue;
						}
						temp++;				
					}
				}
			}
			if (qqq == 2)
				temp += 2;
    	}
		if (temp==6) {	//적중한게 있다
			answer++;
			for (int b = 0, i_ = i; b < 2; b++,i_++) {
				for (int c = 0, j_ = j; c < 3; c++,j_++) {
					possible[j_] = 0;
					if (board[i_][j_] != 0) board[i_][j_] = 0;						
				}
			}
			checkline(possible, board);
			return true;
		}
	}
	return false;
}

bool checksero(vector<int> &possible, vector<vector<int>> &board, int i, int j, int &answer) {
	for (int a = 0; a < sero.size(); a++) {
		int temp = 0;		//일치율
		int block = 0;
		for (int c = 0, j_ = j; c < 2; c++, j_++) {
			int qqq = 0;
			for (int b = 0, i_ = i; b < 3; b++, i_++) {
				if (sero[a][b][c] == board[i_][j_] || (sero[a][b][c]>0 && board[i_][j_]>0)) {
					if (sero[a][b][c] == 0) {
						temp++;
						continue;
					}
					if (block == 0 || board[i_][j_] == block) {
						block = board[i_][j_];
						if (possible[j_] != board[i_][j_]) {
							qqq++;
							continue;
						}
						temp++;
					}
				}
			}
			if (qqq == 3)
				temp += 3;
		}
			if (temp == 6) {	//적중한게 있다
			answer++;
			for (int b = 0,i_=i; b < 3; b++, i_++) {					
				for (int c = 0,j_=j; c < 2; c++, j_++) {
					possible[j_] = 0;
					if (board[i_][j_] != 0) board[i_][j_] = 0;
				}
			}
			checkline(possible, board);
			return true;
		}
	}
	return false;
}