#20061シミュレーション、モノラルデュアルチャネルc++を実施


#20061モノラルモノラル2
これは問題と同じくらい難しい問題です.特に座標...

Solution


  • 関数は、ほぼT形状で青、緑のセルに移動する関数moveBlock(t,y,x)、青のセルのブロックマージmergeBlue()、緑のセルのブロックマージmergeGreen()がある
  • まず1つの密格の上のブロックを調べて、もし1行あるいは列がいっぱいになったら、その格を取り除いて、残りの格を合わせて、更に1つの軟格を調べて、もしブロックがあれば、末尾の格から取り除いて、合わせて
  • 🎲1. Move Block

  • 1*1 t1모양Blue:ブロックが右側になるまでブロックを移動し、ブロックを適切な位置に配置します.
    緑:下部のブロックを移動し、その位置に配置する
  • .
    	if (t == 1) {
    		//move to blue
    		int nx = x;
    		while (nx < mapSize - 1 && !map[y][nx + 1])
    			nx++;
    		map[y][nx] = 1;
    		//move to green
    		int ny = y;
    		while (ny < mapSize - 1 && !map[ny + 1][x])
    			ny++;
    		map[ny][x] = 1;
    	}
  • 1*2 t2모양Blue:右側に移動してブロックがある場合は、ブロックを左側に置き、その位置に対して左側に2マス水平に置きます.
    Green:最初に配置されたブロックのセルが(y,x)(y,x+1)の場合、ブロック(ny,x)(ny,x+1)が配置されるまで、次の2つの水平に連続するセルのいずれかに移動します.
    	//1*2 block
    	else if (t == 2) {
    		//move to blue
    		int nx = x + 1;
    		while (nx < mapSize - 1 && !map[y][nx + 1])
    			nx++;
    		map[y][nx] = 1; map[y][nx - 1] = 1;
    		//move to green 
    		int ny = y + 1;
    		while (ny < mapSize - 1 && !map[ny + 1][x] && !map[ny + 1][x + 1])
    			ny++;
    		map[ny][x] = 1; map[ny][x + 1] = 1;
    	}
  • 2*1 t3모양Blue:最初にブロックを配置したセルが(y,x)(y+1,x)の場合、隣接する2つの垂直に連続したセルのいずれかに移動し、ブロック(y,nx)(y+1,nx)の位置にブロックを配置する
    緑:ブロックを下に移動し、その位置に基づいて2つのスペース
  • を上に配置します.
    	//2*1 block
    	else if (t == 3) {
    		//move to blue 
    		int nx = x + 1;
    		while (nx < mapSize - 1 && !map[y][nx + 1] && !map[y + 1][nx + 1])
    			nx++;
    		map[y][nx] = 1; map[y + 1][nx] = 1;
    		//move to green
    		int ny = y + 1;
    		while (ny < mapSize - 1 && !map[ny + 1][x])
    			ny++;
    		map[ny][x] = 1; map[ny - 1][x] = 1;
    	}

    🎲2. Merge Blue/Green


    (青い格子しか見えません)
  • の密格が1つしか表示されない場合、1つの列がブロックに満ちている場合、その数はremoveの
  • に保存される.
  • startは、満列の中で最大の列番号
  • を格納する.
    	//count number of merging cols
    	for (int x = 6; x < mapSize; x++) {
    		for (int y = 0; y <= 3; y++) {
    			if (map[y][x] == 0) break;
    			if (y == 3) {
    				start = x;
    				remove++;
    			}
    		}
    	}
  • を満たす最大列から、前面にそれぞれ1つのシフト格子を引き出し、
  • を保存する.
    	//merge from 4 to 9 clos
    	if (start > -1) {
    		for (int x = start - remove; x >= 4; x--) {
    			for (int y = 0; y <= 3; y++) {
    				map[y][x + remove] = map[y][x];
    				map[y][x] = 0;
    			}
    		}
    	}
  • は、2つの透明な4、5列のうち、1つのブロックのみの列数
  • を記憶する.
    	int cols = 0;
    	for (int x = 4; x <= 5; x++) {
    		for (int y = 0; y <= 3; y++) {
    			if (map[y][x] == 1) {
    				cols++; break;
    			}
    		}
    	}
  • 列の個数で最後尾から引きずり出して保存し、4、5、番号は空
  • とする.
    	if (cols > 0) {
    		for (int x = 9 - cols; x >= 4; x--) {
    			for (int y = 0; y <= 3; y++) {
    				map[y][x + cols] = map[y][x];
    			}
    		}
    		for (int x = 4; x <= 5; x++)
    			for (int y = 0; y <= 3; y++)
    				map[y][x] = 0;
    	}

    Sorce Code

    #include <iostream>
    
    using namespace std;
    const int mapSize = 10;
    
    int map[mapSize][mapSize];
    int score = 0;
    
    void mergeBlue() {
    	int start = -1;
    	int remove = 0;
    	//count number of merging cols
    	for (int x = 6; x < mapSize; x++) {
    		for (int y = 0; y <= 3; y++) {
    			if (map[y][x] == 0) break;
    			if (y == 3) {
    				start = x;
    				remove++;
    			}
    		}
    	}
    	score += remove;
    	//merge from 4 to 9 clos
    	if (start > -1) {
    		for (int x = start - remove; x >= 4; x--) {
    			for (int y = 0; y <= 3; y++) {
    				map[y][x + remove] = map[y][x];
    				map[y][x] = 0;
    			}
    		}
    	}
    
    	//print();
    
    	//check 4-5 cols
    	int cols = 0;
    	for (int x = 4; x <= 5; x++) {
    		for (int y = 0; y <= 3; y++) {
    			if (map[y][x] == 1) {
    				cols++; break;
    			}
    		}
    	}
    	//merge from 4 to 9 cols
    	if (cols > 0) {
    		for (int x = 9 - cols; x >= 4; x--) {
    			for (int y = 0; y <= 3; y++) {
    				map[y][x + cols] = map[y][x];
    			}
    		}
    		for (int x = 4; x <= 5; x++)
    			for (int y = 0; y <= 3; y++)
    				map[y][x] = 0;
    	}
    	//print();
    }
    
    void mergeGreen() {
    	int start = -1;
    	int remove = 0;
    	//count number of merging rows
    	for (int y = 6; y < mapSize; y++) {
    		for (int x = 0; x <= 3; x++) {
    			if (map[y][x] == 0) break;
    			if (x == 3) {
    				start = y;
    				remove++;
    			}
    		}
    	}
    	score += remove;
    	//merge from 4 to 9 rows
    	if (start > -1) {
    		for (int y = start - remove; y >= 4; y--) {
    			for (int x = 0; x <= 3; x++) {
    				map[y+remove][x] = map[y][x];
    				map[y][x] = 0;
    			}
    		}
    	}
    	//check 4-5 rows
    	int rows = 0;
    	for (int y = 4; y <= 5; y++) {
    		for (int x = 0; x <= 3; x++) {
    			if (map[y][x] == 1) {
    				rows++; break;
    			}
    		}
    	}
    	//merge from 4 to 9 rows
    	if (rows > 0) {
    		for (int y = 9 - rows; y >= 4; y--) {
    			for (int x = 0; x <= 3; x++) {
    				map[y+rows][x] = map[y][x];
    			}
    		}
    		for (int y = 4; y <= 5; y++)
    			for (int x = 0; x <= 3; x++)
    				map[y][x] = 0;
    	}
    
    	//print();
    }
    
    void moveBlock(int t, int y, int x) {
    	//1*1 block
    	if (t == 1) {
    		//move to blue
    		int nx = x;
    		while (nx < mapSize - 1 && !map[y][nx + 1])
    			nx++;
    		map[y][nx] = 1;
    		//move to green
    		int ny = y;
    		while (ny < mapSize - 1 && !map[ny + 1][x])
    			ny++;
    		map[ny][x] = 1;
    	}
    	//1*2 block
    	else if (t == 2) {
    		//move to blue
    		int nx = x + 1;
    		while (nx < mapSize - 1 && !map[y][nx + 1])
    			nx++;
    		map[y][nx] = 1; map[y][nx - 1] = 1;
    		//move to green 
    		int ny = y + 1;
    		while (ny < mapSize - 1 && !map[ny + 1][x] && !map[ny + 1][x + 1])
    			ny++;
    		map[ny][x] = 1; map[ny][x + 1] = 1;
    	}
    	//2*1 block
    	else if (t == 3) {
    		//move to blue 
    		int nx = x + 1;
    		while (nx < mapSize - 1 && !map[y][nx + 1] && !map[y + 1][nx + 1])
    			nx++;
    		map[y][nx] = 1; map[y + 1][nx] = 1;
    		//move to green
    		int ny = y + 1;
    		while (ny < mapSize - 1 && !map[ny + 1][x])
    			ny++;
    		map[ny][x] = 1; map[ny - 1][x] = 1;
    	}
    }
    
    void input() {
    	int N;
    	cin >> N;
    	for (int i = 0; i < N; i++) {
    		int t, y, x;
    		cin >> t >> y >> x;
    		moveBlock(t, y, x);
    		mergeBlue();
    		mergeGreen();
    	}
    }
    
    int countBlock() {
    	int cnt = 0;
    	for (int y = 0; y <= 3; y++)
    		for (int x = 4; x < mapSize; x++)
    			cnt += map[y][x];
    	for (int y = 4; y < mapSize; y++)
    		for (int x = 0; x <= 3; x++)
    			cnt += map[y][x];
    	return cnt;
    }
    
    int main() {
    	input();
    	cout << score << endl;
    	cout << countBlock() << endl;
    	return 0;
    }