zoukankan      html  css  js  c++  java
  • 搜索题【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
    ",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;
    }
    
  • 相关阅读:
    数据库面试题
    MySQL表的导入
    MySQL表的导出
    MySQL安装mydumper
    MySQL中的日志
    动态数组实现下压栈
    动态数组
    设计模式之迭代器
    设计模式之组合模式
    设计模式之状态模式
  • 原文地址:https://www.cnblogs.com/Sparks-Pion/p/9695946.html
Copyright © 2011-2022 走看看