Cu ball
```cpp
#include<bits/stdc++.h>
using namespace std;
const int N=10;
int t,n=7,m=5,a[N][N],ans[N][3];
struct node{
int ans1[N],ans2[N],ans3[N];//搜索中的答案存储
}x;
bool check(){//检查游戏是否通关
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]!=0){//如果还有数没有被消除,说明还未通关
return false;
}
}
}
return true;
}
bool Check(){//检查当前解是否为字典序最小的解
for(int i=1;i<=t;i++){
if(ans[i][0]>x.ans1[i]){//判断第一关键字 越小越好
return false;
}
else if(ans[i][0]==x.ans1[i]){
if(ans[i][1]>x.ans2[i]){//判断第二关键字 越小越好
return false;
}
else if(ans[i][1]==x.ans2[i]){
if(ans[i][2]<x.ans3[i]){//判断第三关键字 越大越好
return false;
}
}
}
}
return true;
}
void delet(){//进行消除方块操作
for(int i=1;i<=m;i++){//对每一列进行下落操作
int now=0,c[N];
for(int j=n;j>=1;j--){
if(a[j][i]!=0){
c[++now]=a[j][i];
}
}
for(int j=1;j<=now;j++){
a[n-j+1][i]=c[j];
}
}
while(1){
bool f[N][N];
memset(f,false,sizeof f);
bool F=false;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i-1][j]==a[i][j]&&a[i][j]==a[i+1][j]){
F=f[i][j]=true;
}
if(a[i-2][j]==a[i-1][j]&&a[i-1][j]==a[i][j]){
F=f[i][j]=true;
}
if(a[i][j]==a[i+1][j]&&a[i+1][j]==a[i+2][j]){
F=f[i][j]=true;
}
if(a[i][j-1]==a[i][j]&&a[i][j]==a[i][j+1]){
F=f[i][j]=true;
}
if(a[i][j-2]==a[i][j-1]&&a[i][j-1]==a[i][j]){
F=f[i][j]=true;
}
if(a[i][j]==a[i][j+1]&&a[i][j+1]==a[i][j+2]){
F=f[i][j]=true;
}
}
}
if(F==false||check()){
break;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(f[i][j]==true){
a[i][j]=0;//删除
}
}
}
for(int i=1;i<=m;i++){//对每一列进行下落操作
int now=0,c[N];
for(int j=n;j>=1;j--){
if(a[j][i]!=0){
c[++now]=a[j][i];
}
}
for(int j=1;j<=now;j++){
a[n-j+1][i]=c[j];
}
}
}
}
void dfs(int tot,node x){//tot 表示当前的移动次数,(ans1[tot],ans2[tot])表示要移动的方块的坐标,ans[3]表示移动的方向,1,表示向右移动,-1表示向左移动
cout<<"-----------------"<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
cout<<"-----------------"<<endl;
if(check()&&tot<=t){//是否在未达到要求的通关步数前就已经通关
return;
}
if(tot==t){// 通关步数已经达到了要求的通关步数
if(check()){//检查是否通关
if(Check()==true){//检查当前解是否为字典序最小的解
for(int i=1;i<=t;i++){//存储当前解
ans[i][0]=x.ans1[i],ans[i][1]=x.ans2[i],ans[i][2]=x.ans3[i];
}
}
}
return;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){//选择移动哪一个坐标
if(a[i][j]!=0){//若该坐标上有方块,则可以移动
{//该方块向右移动
int nxt=tot+1;
x.ans1[nxt]=i,x.ans2[nxt]=j,x.ans3[nxt]=1;
int dx=i,dy=j+1;//计算与该方块交换的位置
if(dy<=m){//若与该方块交换的位置在游戏界面内
if(a[dx][dy]==0){//若与该方块交换的位置没有方块,即该方块要从目标位置掉落
int b[N][N];
for(int ii=1;ii<=n;ii++){
for(int jj=1;jj<=m;jj++){
b[ii][jj]=a[ii][jj];//记录当前游戏界面
}
}
swap(a[i][j],a[dx][dy]);//交换位置
delet();//进行方块删除操作
dfs(nxt,x);
for(int ii=1;ii<=n;ii++){
for(int jj=1;jj<=m;jj++){
a[ii][jj]=b[ii][jj];//回溯
}
}
}
else{//若与该方块交换的位置有方块
int b[N][N];
for(int ii=1;ii<=n;ii++){
for(int jj=1;jj<=m;jj++){
b[ii][jj]=a[ii][jj];//记录当前游戏界面
}
}
swap(a[i][j],a[dx][dy]);//交换位置
delet();//进行方块删除操作
dfs(nxt,x);
for(int ii=1;ii<=n;ii++){
for(int jj=1;jj<=m;jj++){
a[ii][jj]=b[ii][jj];//回溯
}
}
}
}
}
{//该方块向左移动
int nxt=tot+1;
x.ans1[nxt]=i,x.ans2[nxt]=j,x.ans3[nxt]=-1;
int dx=i,dy=j-1;//计算与该方块交换的位置
if(dy>=1){//若与该方块交换的位置在游戏界面内
if(a[dx][dy]==0){//若与该方块交换的位置没有方块,即该方块要从目标位置掉落
int b[N][N];
for(int ii=1;ii<=n;ii++){
for(int jj=1;jj<=m;jj++){
b[ii][jj]=a[ii][jj];//记录当前游戏界面
}
}
swap(a[i][j],a[dx][dy]);//交换位置
delet();//进行方块删除操作
dfs(nxt,x);
for(int ii=1;ii<=n;ii++){
for(int jj=1;jj<=m;jj++){
a[ii][jj]=b[ii][jj];//回溯
}
}
}
else{//若与该方块交换的位置有方块
int b[N][N];
for(int ii=1;ii<=n;ii++){
for(int jj=1;jj<=m;jj++){
b[ii][jj]=a[ii][jj];//记录当前游戏界面
}
}
swap(a[i][j],a[dx][dy]);//交换位置
delet();//进行方块删除操作
dfs(nxt,x);
for(int ii=1;ii<=n;ii++){
for(int jj=1;jj<=m;jj++){
a[ii][jj]=b[ii][jj];//回溯
}
}
}
}
}
}
}
}
}
signed main(){
scanf("%d",&t);
for(int i=1;i<=t;i++){
ans[i][0]=ans[i][1]=ans[i][2]=0x3f3f3f3f;
ans[i][2]=-ans[i][2];
}//初始化答案数组
int X;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
scanf("%d",&X);
if(X==0){
break;
}
a[n-j+1][i]=X;
}
}
dfs(0,x);//搜索答案
if(ans[1][0]==0x3f3f3f3f){//如果没有就解决方案
puts("-1");
return 0;
}
for(int i=1;i<=t;i++){
printf("%d %d %d\n",ans[i][0],ans[i][1],ans[i][2]);
}//输出答案
return 0;
}
```
全 T 了qwq
by pandaSTT @ 2022-02-25 21:28:30
凡尔赛条约是你签的吗
by landernal @ 2022-02-25 21:49:00
fAKe
by ttttalk @ 2022-02-26 11:10:39