题意
在一个7行5列的期盘中,有至多10种颜色的方块。当这些方块下方空的时候,这些方块总是会垂直掉落#### 当有3个颜色相同的方块排成一行或一列时,它们会被同时消除
你需要在给定的步数内,通过调换相邻方块,使棋盘上没有方块。
若做不到,输出-1;不然输出1种方法(要移动的方块的x、y坐标 + 移动方向) (移动方向 1 = 右移,-1 = 左移)
【注】当有多组解时,以x为第1关键字,以y为第2关键字,且1优于-1。故输出是唯一的
【注】棋盘读入格式:共有5行,每行以0结尾,代表从左至右每列上从下到上的方块颜色,每行至多8个数
题解
还是比较常规的dfs题
按照题意来,每次dfs枚举要移动的方块时,以x为第1关键字,以y为第2关键字
右移条件:首先选定的格子要有方块;其次右边有格子,且要交换的两个方块颜色不同
左移条件:首先选定的格子要有方块;其次左边有格子,且左边没有方格(不然还不如右移)
移完判断清除和掉落,若步数大于n或当前有任意颜色的棋子只有1、2个,则return
若条件符合,直接输出
调试记录
Class里面把‘N’达成‘n’
以后再也不用大小写分辨变量了~~
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define N 7
#define M 5
using namespace std;
void Swap(int &a, int &b){
a ^= b ^= a ^= b;
}
int n, x[11], y[11], p[11];
class class_table{
public:
int table[N + 1][M + 1], num[11];
class_table(){
memset(this, 0, sizeof this);
}
bool Clear(){
bool empty[N + 1][M + 1], res = false;
memset(empty, 0, sizeof(empty));
for (int i = 1; i <= N; i++){
for (int j = 1; j <= M; j++){
if (i >= 3 && table[i][j] == table[i - 1][j] && table[i - 1][j] == table[i - 2][j] && table[i][j])
empty[i][j] = empty[i - 1][j] = empty[i - 2][j] = true;
if (j >= 3 && table[i][j] == table[i][j - 1] && table[i][j - 1] == table[i][j - 2] && table[i][j])
empty[i][j] = empty[i][j - 1] = empty[i][j - 2] = true;
}
}
for (int i = 1; i <= N; i++){
for (int j = 1; j <= M; j++){
if (empty[i][j]) num[table[i][j]]--, table[i][j] = 0, res = true;
}
}
return res;
}
void Drop(){
for (int j = 1; j <= M; j++){
int tmp[8], cnt = 0;
for (int i = 1; i <= N; i++){
if (table[i][j]) tmp[++cnt] = table[i][j];
}
for (int i = 1; i <= cnt; i++) table[i][j] = tmp[i];
for (int i = cnt + 1; i <= N; i++) table[i][j] = 0;
}
}
void Swap(int x1, int y1, int x2, int y2){
:: Swap(table[x1][y1], table[x2][y2]);
this -> Drop();
while (this -> Clear()) this -> Drop();
}
bool Invalid(){
for (int i = 1; i <= 10; i++) if (num[i] == 1 || num[i] == 2) return true;
return false;
}
bool Finished(){
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++) if (table[i][j]) return false;
return true;
}
} now;
void Print(int dep){
for (int i = 1; i <= dep; i++) printf("%d %d %d\n", x[i], y[i], p[i]);
}
void Dfs(int dep){
if (now.Invalid()) return;
if (now.Finished()) Print(dep - 1), exit(0);
if (dep > n) return;
class_table temp = now;
for (int j = 1; j <= M; j++){
for (int i = 1; i <= N; i++){
if (temp.table[i][j]){
if (j < M && temp.table[i][j] != temp.table[i][j + 1]){
now = temp;
now.Swap(i, j, i, j + 1);
x[dep] = j - 1; y[dep] = i - 1; p[dep] = 1;
Dfs(dep + 1);
}
if (j > 1 && !temp.table[i][j - 1]){
now = temp;
now.Swap(i, j, i, j - 1);
x[dep] = j - 1; y[dep] = i - 1; p[dep] = -1;
Dfs(dep + 1);
}
}
}
}
}
int main(){
scanf("%d", &n);
int X;
for (int i = 1; i <= M; i++)
for (int j = 1; scanf("%d", &X); ++j) if (X) ++now.num[now.table[j][i] = X]; else break;
Dfs(1); printf("-1\n");
return 0;
}