[BOJ]2100号2048(Easy)c++
69695 ワード
https://www.acmicpc.net/problem/12100
質問する
2048ゲームは4×4サイズの碁盤で独自に楽しむ面白いゲーム.このリンクをクリックするとゲームができます.このゲームでは、1回の移動は、ボード上のブロック全体を上下左右4方向の1つに移動します.同じ値を持つ2つのブロックが衝突すると、2つのブロックが1つに結合されます.1回の移動では、マージされたブロックは別のブロックと再マージできません.(実際のゲームでは、移動するたびにブロックが追加されますが、この問題ではブロックは追加されません)
<図1>では、ブロックを上に移動すると<図2>の状態となる.ここで、ブロックを左に移動すると<図3>の状態となる.
<図4>の状態で、ブロックを右へ<図5>に移動し、ここでさらに上へ移動するブロックは<図6>である.ここから1ブロック右に移動すると、<図7>が生成されます.
<図8>の状態でブロックを左に移動したらどうなりますか?2は衝突しているので4に統合されて『図9』の状態になります.
<図10>でブロックを上に移動すると<図11>の状態となる.<図12においては、1回の移動中にマージされたブロックがマージされないため、ブロックを上へ移動すると<図13>の状態となる.
最後に、同じ数が3つある場合は、移動するセルを最初にマージします.たとえば、上に移動すると、上のブロックが最初に結合されます.<図14>のように、上に移動すると<図15>が作成される.
この問題に関連する2048ゲームのマザーボードのサイズはNです.×Nです.回路基板のサイズと回路基板のブロック状態が指定されている場合は、最大5回まで移動できるプログラムを作成します.
入力します.
3
2 2 2
4 4 4
8 8 8
出力します.
16
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int N;
int board[6][20][20];
bool visit[20][20] = {false,};
int maxval = 0;
bool flag;
void init(int x) {
memcpy(board[x], board[x - 1], sizeof(board[0]));
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
visit[i][j] = false;
}
}
}
void y_visit(int y, int z, int w) {
visit[y][w] = false;
visit[z][w] = true;
}
void x_visit(int y, int z, int w) {
visit[w][y] = false;
visit[w][z] = true;
}
int move(int x, int dir) {
flag = false;
init(x);
switch(dir) {
case 0:
for(int i = N - 2; i >= 0; i--) {
for(int j = 0; j < N; j++) {
if(board[x][i + 1][j] > 0 && board[x][i][j] == 0) {
board[x][i][j] = board[x][i + 1][j];
if(visit[i + 1][j])
y_visit(i + 1, i, j);
flag = true;
for(int k = i + 1; k < N - 1; k++) {
board[x][k][j] = board[x][k + 1][j];
visit[k][j] = visit[k + 1][j];
}
board[x][N - 1][j] = 0;
visit[N - 1][j] = false;
}
}
}
for(int i = 0; i < N - 1; i++) {
for(int j = 0; j < N; j++) {
if(board[x][i + 1][j] > 0) {
if((board[x][i + 1][j] == board[x][i][j]) && !visit[i + 1][j] && !visit[i][j]) {
board[x][i][j] = board[x][i + 1][j] + board[x][i][j];
maxval = max(maxval, board[x][i][j]);
y_visit(i + 1, i, j);
flag = true;
for(int k = i + 1; k < N - 1; k++) {
board[x][k][j] = board[x][k + 1][j];
visit[k][j] = visit[k + 1][j];
}
board[x][N - 1][j] = 0;
visit[N - 1][j] = false;
}
}
}
}
break;
case 1:
for(int i = 1; i < N; i++) {
for(int j = 0; j < N; j++) {
if(board[x][i - 1][j] > 0 && board[x][i][j] == 0) {
board[x][i][j] = board[x][i - 1][j];
if(visit[i - 1][j])
y_visit(i - 1, i, j);
flag = true;
for(int k = i - 1; k > 0; k--) {
board[x][k][j] = board[x][k - 1][j];
visit[k][j] = visit[k - 1][j];
}
board[x][0][j] = 0;
visit[0][j] = false;
}
}
}
for(int i = N - 1; i > 0; i--) {
for(int j = 0; j < N; j++) {
if(board[x][i - 1][j] > 0) {
if((board[x][i - 1][j] == board[x][i][j]) && !visit[i - 1][j] && !visit[i][j]) {
board[x][i][j] = board[x][i - 1][j] + board[x][i][j];
maxval = max(maxval, board[x][i][j]);
y_visit(i - 1, i, j);
flag = true;
for(int k = i - 1; k > 0; k--) {
board[x][k][j] = board[x][k - 1][j];
visit[k][j] = visit[k - 1][j];
}
board[x][0][j] = 0;
visit[0][j] = false;
}
}
}
}
break;
case 2:
for(int j = N - 2; j >= 0; j--) {
for(int i = 0; i < N; i++) {
if(board[x][i][j + 1] > 0 && board[x][i][j] == 0) {
board[x][i][j] = board[x][i][j + 1];
if(visit[i][j + 1])
x_visit(j + 1, j, i);
flag = true;
for(int k = j + 1; k < N - 1; k++) {
board[x][i][k] = board[x][i][k + 1];
visit[i][k] = visit[i][k + 1];
}
board[x][i][N - 1] = 0;
visit[i][N - 1] = false;
}
}
}
for(int j = 0; j < N - 1; j++) {
for(int i = 0; i < N; i++) {
if(board[x][i][j + 1] > 0) {
if((board[x][i][j + 1] == board[x][i][j]) && !visit[i][j + 1] && !visit[i][j]) {
board[x][i][j] = board[x][i][j + 1] + board[x][i][j];
maxval = max(maxval, board[x][i][j]);
x_visit(j + 1, j, i);
flag = true;
for(int k = j + 1; k < N - 1; k++) {
board[x][i][k] = board[x][i][k + 1];
visit[i][k] = visit[i][k + 1];
}
board[x][i][N - 1] = 0;
visit[i][N - 1] = false;
}
}
}
}
break;
case 3:
for(int j = 1; j < N; j++) {
for(int i = 0; i < N; i++) {
if(board[x][i][j - 1] > 0 && board[x][i][j] == 0) {
board[x][i][j] = board[x][i][j - 1];
if(visit[i][j - 1])
x_visit(j - 1, j, i);
flag = true;
for(int k = j - 1; k > 0; k--) {
board[x][i][k] = board[x][i][k - 1];
visit[i][k] = visit[i][k - 1];
}
board[x][i][0] = 0;
visit[i][0] = false;
}
}
}
for(int j = N - 1; j > 0; j--) {
for(int i = 0; i < N; i++) {
if(board[x][i][j - 1] > 0) {
if((board[x][i][j - 1] == board[x][i][j]) && !visit[i][j - 1] && !visit[i][j]) {
board[x][i][j] = board[x][i][j - 1] + board[x][i][j];
maxval = max(maxval, board[x][i][j]);
x_visit(j - 1, j, i);
flag = true;
for(int k = j - 1; k > 0; k--) {
board[x][i][k] = board[x][i][k - 1];
visit[i][k] = visit[i][k - 1];
}
board[x][i][0] = 0;
visit[i][0] = false;
}
}
}
}
break;
}
return flag;
}
void num(int x) {
if(x == 6)
return;
for(int dir = 0; dir < 4; dir++) {
if(!move(x, dir))
continue;
num(x + 1);
}
}
int main() {
scanf("%d", &N);
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
scanf("%d", &board[0][i][j]);
maxval = max(maxval, board[0][i][j]);
}
}
num(1);
printf("%d\n", maxval);
}
最大5回まで移動可能で、再帰関数を使用して移動回数を増やします.4つの方向を方向1,2,3,4と呼ぶ.K(0
4時間ぐらいかかりました.コードが汚いのですが、今日はもうやりたくないのでアップしました.Easyバージョンは私にとっても難しいです.Hardバージョンも次回にリリースします.😐
Reference
この問題について([BOJ]2100号2048(Easy)c++), 我々は、より多くの情報をここで見つけました https://velog.io/@chowisely/BOJ-12100テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol