题目略
我们把空白看成0,那么共有4种移动方法
x优先于y,可以通过循环实现
1优先于-1,看下面
我们必须保证第一个搜到的就是最优解,搜到解就return
- 空白,跳过
- 不在右边界,右移
- 右边界且左边为0(若左边不是空,从左边格子右移更优),左移
- 不在左右边界且左边为0(因为这种前面没办法右移完成),左移
接下来看代码
我这里的dfs(nn)
是指进行第nn
次移动
所以在memcpy
之前一定要记得nn-1
!!!
因为这个卡了好久QAQ
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int n;
int x=0;
int m[10][10][15];
int book[6][8];
int a[10],b[10],c[10];
void fall(int nn,int x)
{
int k=-1;
int i=0;
while(i<7)
{
if(k!=-1 && m[nn][x][i])
{
int j=i;
m[nn][x][k]=m[nn][x][i];
while(m[nn][x][j] && j<7)
{
k++;
j++;
m[nn][x][k]=m[nn][x][j];
}
for(int u=k+1;u<(j<=7?j:7);u++)
{
m[nn][x][u]=0;//没有被赋值的置为0
}
//m[nn][x][j]等于0 最后一个把值赋给了其他人的是m[nn][x][j-1]
i=k+1;//此时m[nn][x][k]=0
}
else if(k==-1 && !m[nn][x][i])//只有第一次要用到这个 不然会出错
{
k=i;
i++;
}
else i++;
}
}
int check(int nn)
{
int changed=0;
memset(book,0,sizeof(book));
for(int i=0;i<5;++i)
{
for(int j=0;j<7;++j)
{
if(m[nn][i][j]==m[nn][i+1][j] && m[nn][i][j]==m[nn][i+2][j] && m[nn][i][j]!=0)
//千万不能写连等 QAQ
{
changed=1;
book[i][j]=1;
book[i+1][j]=1;
book[i+2][j]=1;
}
if(m[nn][i][j]==m[nn][i][j+1] && m[nn][i][j]==m[nn][i][j+2] && m[nn][i][j]!=0)
{
changed=1;
book[i][j]=1;
book[i][j+1]=1;
book[i][j+2]=1;
}
}
}
if(changed)
{
for(int i=0;i<5;++i)
{
for(int j=0;j<7;++j)
{
if(book[i][j]) m[nn][i][j]=0;
}
}
}
return changed;
}
int dfs(int nn)
{
if(nn>n)
{
for(int i=0;i<5;++i)
{
if(m[n][i][0]) return 0;
}
return 1;
}
for(int i=0;i<5;++i)
{
for(int j=0;j<7;++j)
{
if(!m[nn-1][i][j]) continue;//m[nn]也没有定义...
if(i<4) c[nn]=1;//不在右边界 优先右移
else if(i==4 && !m[nn-1][i-1][j]) c[nn]=-1;//在右边界且左边是0
//nn-1//nn-1//nn-1//
else continue;
a[nn]=i;
b[nn]=j;
memcpy(m[nn],m[nn-1],sizeof(m[nn-1]));
swap(m[nn][i][j],m[nn][i+c[nn]][j]);
do{
for(int p=0;p<5;++p)
{
fall(nn,p);
}
}while(check(nn));
if(dfs(nn+1))
{
return 1;
}
if(i>0 && i<4 && !m[nn][i-1][j])//不在左右边界且左边是0
{
a[nn]=i;
b[nn]=j;
c[nn]=-1;
memcpy(m[nn],m[nn-1],sizeof(m[nn-1]));
swap(m[nn][i][j],m[nn][i-1][j]);
do{
for(int p=0;p<5;++p)
{
fall(nn,p);
}
}while(check(nn));
if(dfs(nn+1)) return 1;
}
}
}
return 0;
}
int main(){
memset(m,0,sizeof(m));
scanf("%d",&n);
for(int i=0;i<5;++i)
{
int j=0;
do{
scanf("%d",&m[0][i][j]);
j++;
}while(m[0][i][j-1]);//m[0][i][j]还没有定义
}
x=dfs(1);
if(x)
{
for(int i=1;i<=n;++i)
{
printf("%d %d %d\n",a[i],b[i],c[i]);
}
}
else printf("-1\n");
return 0;
}