Mayan游戏

题目描述

给个链接门..........
https://www.luogu.org/problem/show?pid=1312#sub

解释:

两次A的题目,就是妥妥暴力

判断点是否存在,存在就换着试试。。

优化的剪枝:如果和右边(下面)颜色不一样就换走,如果左边(上面)是空的就换走

说说一开始犯的zz的错误。

1.降落时可以降落好多格【捂脸】

2.拷贝的b数组应该用局部变量。如果是全局变量,复原过程就不再正确

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int a[5][7],x[10],y[10],z[10];
bool ff=false;
int n,m;
int xc()
{
	int i,j;
	bool dis[5][7];
	memset(dis,0,sizeof(dis));
	for (i=0;i<=4;i++)//降落 
	  for (j=1;j<=6;j++)
	    if (a[i][j])
	    {
	    	int k=1;
	    	while (k<=j && a[i][j-k]==0) swap(a[i][j-k],a[i][j-k+1]),k++;
		}
	      
	for (i=0;i<=4;i++)//消除过程 
	  for (j=0;j<=6;j++)
	    if (a[i][j])
	  {
	  	if (i<3 && a[i][j]==a[i+1][j] && a[i][j]==a[i+2][j])
	  	  {
	  	  	dis[i][j]=true; dis[i+1][j]=true; dis[i+2][j]=true; 
	  	  	int k=i+2;
			while (k<4 && a[k][j]==a[k+1][j])
			  dis[++k][j]=true;
		  }
		if (j<5 && a[i][j]==a[i][j+1] && a[i][j]==a[i][j+2])
		{
			dis[i][j]=true; dis[i][j+1]=true; dis[i][j+2]=true; 
	  	  	int k=j+2;
			while (k<6 && a[i][j]==a[i][k+1])
			  dis[i][++k]=true;
		} 
	  }
	int rr=0;
	for (i=0;i<=4;i++)
	  for (j=0;j<=6;j++)
	    if (dis[i][j]) a[i][j]=0,rr++;
	if (rr==0) return rr;
	rr+=xc();
	return rr;
}
void dfs(int t,int yu)
{
	int b[5][7];
	if (ff) return;
	int i,j;
	if (t>n)
	  {
	  	if (!yu)
	  	{
	  		for (i=1;i<=n;i++)
	  		  printf("%d %d %d\n",x[i],y[i],z[i]);
	  		ff=true;
		}
		return;
	  }	  
	  
	  for (i=0;i<=4;i++)//拷贝  
	    for (j=0;j<=6;j++)
	      b[i][j]=a[i][j]; 
	      
	  for (i=0;i<=4;i++)
	    for (j=0;j<=6;j++)
	      if (a[i][j])
	    {	    	
	        bool flag=true;
	    	x[t]=i; y[t]=j; 
	    	if (i<4 && a[i][j]!=a[i+1][j])
	    	{
	    		z[t]=1;
	    		swap(a[i][j],a[i+1][j]);
	    		int now=yu-xc();
	    		dfs(t+1,now);
	    		flag=false;
			}
			if (!flag)
		      {
		        for (int ii=0;ii<=4;ii++)//复原 
	              for (int jj=0;jj<=6;jj++)
	                 a[ii][jj]=b[ii][jj];
		        
	            flag=true;
			  } 
			if (i && !a[i-1][j])
			{
				z[t]=-1;
				swap(a[i][j],a[i-1][j]);
	    	    int now=yu-xc();
	    		dfs(t+1,now);
	    		flag=false;	    
			}
			if (!flag)
			  {
			  	for (int ii=0;ii<=4;ii++)//复原 
	              for (int jj=0;jj<=6;jj++)
	                a[ii][jj]=b[ii][jj];
	            flag=true;
			  } 
		}
}
int main()
{
	int i,j;
	scanf("%d",&n);
	for (i=0;i<=4;i++)
	  for (j=0;j<=7;j++)
	  {
	  	scanf("%d",&a[i][j]);
	  	if (a[i][j]) m++;
	  	else break;
	  }
	dfs(1,m);    
	if (!ff) printf("-1");
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值