题解 P1312 【Mayan游戏】
蒟蒻花了几个小时才调出来,其实只要一道暴力搜索,基本不用剪枝。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int get[10][10];\\初始的棋盘;
int m;
struct node
{
int x,y,z;\\用结构体记录答案;
};
node ans[10];
int tot[10][10];
int finish;\\进行判断,是否找到解,避免超时;
void print()\\输出函数;
{
for(int i=1;i<=m;i++)
printf("%d %d %d\n",ans[i].x-1,ans[i].y-1,ans[i].z);
}
void dfs(int p[10][10],int num)
{
if(finish==1)return;
if(num>m)
{
int f=0;
for(int i=1;i<=5;i++)
for(int j=1;j<=7;j++)
if(p[i][j])\\当到达次数时遍历棋盘是否为空;
f=1;
if(f==0)\\为空输出;
{
print();
finish=1;
}
return;
}
for(int k=1;k<=4;k++)\\可以吧空的点当做0,每个点只向右移;
{
for(int l=1;l<=7;l++)
{
if(p[k][l]!=p[k+1][l])\\一点点剪枝;
{
int tmp[10][10];
for(int i=1;i<=5;i++)
for(int j=1;j<=7;j++)
tmp[i][j]=p[i][j];
swap(tmp[k][l],tmp[k+1][l]);\\移动;
int flag=1;
while(flag==1)\\当能消除时一直消除;
{
flag=0;
int news[10][10];
int h[6];
memset(news,0,sizeof(news));
memset(h,0,sizeof(h));
for(int i=1;i<=5;i++)\\下沉;
for(int j=1;j<=7;j++)
if(tmp[i][j]!=0)
news[i][++h[i]]=tmp[i][j];
int tot[10][10];
memset(tot,0,sizeof(tot));
for(int i=1;i<=5;i++)\\判断可不可以删除,删除几个;
{
for(int j=1;j<=7;j++)
{
if(news[i][j]==0)continue;
int sum1=1,sum2=1;
for(int o=1;o<=5;o++)
{
if(i+o<=5&&news[i+o][j]==news[i][j])
sum1++;
else break;
}
if(sum1>=3)
for(int o=i;o<=i+sum1-1;o++)
tot[o][j]=-1;
for(int o=1;o<=7;o++)
{
if(j+o<=7&&news[i][j+o]==news[i][j])
sum2++;
else break;
}
if(sum2>=3)
for(int o=j;o<=j+sum2-1;o++)
tot[i][o]=-1;
if(sum2>=3||sum1>=3)flag=1;
}
}
for(int i=1;i<=5;i++)
for(int j=1;j<=7;j++)
if(tot[i][j]==-1)
news[i][j]=0;
for(int i=1;i<=5;i++)
for(int j=1;j<=7;j++)
tmp[i][j]=news[i][j];
}
if(p[k][l]!=0)\\因为刚刚假设0可以移动,但实际零不能移动,特判一下移动零的情况;
{
ans[num].x=k;
ans[num].y=l;
ans[num].z=1;
}
else
{
ans[num].x=k+1;
ans[num].y=l;
ans[num].z=-1;
}
dfs(tmp,num+1);
}
}
}
}
int main()
{
scanf("%d",&m);
for(int i=1;i<=5;i++)
{
int x;
for(int j=1;j<=8;j++)
{
scanf("%d",&x);
if(x==0)break;
get[i][j]=x;
}
}
dfs(get,1);
if(finish==0)\\未找到输出-1;
cout<<-1<<endl;
return 0;\\over;
}
第二篇题解望通过,谢谢大佬;