搜索题【1】

题目描述

传送门

题解

对于左右两个相邻非空块,肯定是左边右移而不是右边左移,
那什么时候要枚举左移呢,很显是左边为空块。
这是一个非常重要的剪枝,表示一开始打错,被TLE暴虐……

code

#include <bits/stdc++.h>
#define re register int
using namespace std;
int a[10][10],ans[10][5],vis[10][10],col[11],n,N;
inline int clr(){
    for(re i=9;i;--i)for(re j=9;j;--j)vis[i][j]=1;
    int res=0,l,r,u,d,x,y,t;
    bool f=0;
    for(re i=1;i<=5;++i)for(re j=1;j<=7;++j)
    if(a[i][j]&&((j>=2&&a[i][j-1])||j==1)){
        l=r=i,d=u=j;
        while(l>=2&&a[l-1][j]==a[i][j])--l;
        while(r<=4&&a[r+1][j]==a[i][j])r++;
        while(d>=2&&a[i][d-1]==a[i][j])d--;
        while(u<=6&&a[i][u+1]==a[i][j])u++;
        if(r-l>=2)for(re k=l;k<=r;k++)vis[k][j]=0;
        if(u-d>=2)for(re k=d;k<=u;k++)vis[i][k]=0;
    }
    for(re i=1;i<=5;++i)for(re j=1;j<=7;++j)
    	if(!vis[i][j])res++,a[i][j]=0;
    for(int i=1,j;i<=5;++i){
	    for(j=1;j<=7;++j)if(!a[i][j]) break;
	    if(j==8) continue;x=j;
	    for(   ;j<=7;++j)if(a[i][j]) break;
	    if(j==8) continue;y=j-1,t=0;
	    for(j=x;j<=7;j++){
	    	if(!a[i][y+(++t)]||a[i][j]) break;
	        a[i][j]=a[i][y+t],a[i][y+t]=0,f=1;
	    }
    }
    if(f)res+=clr();return res;
}
inline bool check(){
	int c[11];
    for(re i=10;i;--i)c[i]=0;
    for(re i=5;i;--i)for(re j=7;j;--j)c[a[i][j]]++;
    for(int i=1;i<=N;++i)if(c[i]>=1&&c[i]<=2)return 0;
    return 1;
}
inline void dfs(int step,int last){   
    if(!check()) return;
    if(step>=n+1){ 
	    if(!last){
			for(int i=1;i<=n;i++)
				printf("%d %d %d\n",ans[i][1]-1,ans[i][2]-1,ans[i][3]);
	    	exit(0);
	    }
	    return;
	}
    int t[10][10];
    for(re i=5;i;--i)for(re j=7;j;--j)t[i][j]=a[i][j];
   	for(re i=1;i<=5;++i)for(re j=1;j<=7;++j)if(a[i][j]){
        if(i<=4&&a[i][j]!=a[i+1][j]){
            swap(a[i][j],a[i+1][j]),ans[step][1]=i,ans[step][2]=j,ans[step][3]=1;
            dfs(step+1,last-clr());
            for(re p=5;p;--p)for(re q=7;q;--q)a[p][q]=t[p][q];
        }
        if(i>=2&&!a[i-1][j]){
            swap(a[i][j],a[i-1][j]),ans[step][1]=i,ans[step][2]=j,ans[step][3]=-1;
            dfs(step+1,last-clr());
            for(re p=5;p;--p)for(re q=7;q;--q)a[p][q]=t[p][q];
        }
    }
}
int main(){
    int cnt=0;scanf("%d",&n);
    for(int i=1,j,k=0;i<=5;i++,k=0){
        scanf("%d",&j);
        while(j){
            a[i][++k]=j,++cnt;
			if(!col[j])col[j]=1,++N;
            scanf("%d",&j);
        }
    }
    dfs(1,cnt);printf("-1");return 0;
}
posted @ 2018-09-24 17:04  Sparks_Pion  阅读(168)  评论(0编辑  收藏  举报