【刷题】【搜索】mayan游戏

好复杂

 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
int step; 

struct node
{
    int d[5][7];
    node ()
    { memset(d,0,sizeof(d)); }
    bool operator < (const node & o) const
    {
        for(int i=0;i<5;i++)
            for(int j=0;j<7;j++)
                if(d[i][j]!=o.d[i][j])
                    return d[i][j]<o.d[i][j] ;
        return true;
    }
    
    bool empty()
    {
        for(int i=0;i<5;i++)
            if(d[i][0]) return false;
        return true;
    }
    void down()
    {
        for(int pos=0;pos<5;pos++)
        {
            for(int j=1;j<7;j++)
            {
                if(d[pos][j]==0 || d[pos][j-1]) continue;
                
                int cnt=0;
                while(j>cnt && d[pos][j-cnt-1]==0) cnt++;//j-cnt+1 ~ j-1 都是0 ,j>0
                for(int k=j-cnt,l=j ; k<j && l<7 ; k++,l++)
                    d[pos][k]=d[pos][l],d[pos][l]=0;            
            }
        }
    }
    void to_do(int x,int y,int sd)
    {
        int y1=y,y2=y; 
        while(y1>0 && d[x][y1-1]==sd ) y1--;
        while(y2<6 && d[x][y2+1]==sd ) y2++;
        if(y2-y1+1>=3) 
            for(int i=y1;i<=y2;i++)
                d[x][i]=0;
        
        int x3=x,x4=x; 
        while(x3>0 && d[x3-1][y]==sd ) x3--;
        while(x4<4 && d[x4+1][y]==sd ) x4++;
        if(x4-x3+1>=3) 
            for(int i=x3;i<=x4;i++)
                d[i][y]=0;
    }
    bool clean(int x,int y)
    {
        bool cg=false;
        //先找到一条,然后再延伸 
        int y1=y,y2=y,sd=d[x][y]; 
        while(y1>0 && d[x][y1-1]==sd ) y1--;
        while(y2<6 && d[x][y2+1]==sd ) y2++;
        if(y2-y1+1>=3) 
        {
            cg=true;
            for(int i=y1;i<=y2;i++)
                to_do(x,i,sd);
        }
        //先找到一列,然后再延伸,注意这里x,y可能被清理两遍,所以我用else 
        else
        {
            int x3=x,x4=x; 
            while(x3>0 && d[x3-1][y]==sd ) x3--;
            while(x4<4 && d[x4+1][y]==sd ) x4++;
            if(x4-x3+1>=3) 
            {
                cg=true;
                for(int i=x3;i<=x4;i++)
                    to_do(i,y,sd);
            }
        }
        return cg;
    }
    void change(int x,int y,int xx,int yy)
    {
        swap(d[x][y],d[xx][yy]);
        bool cg=false;
        if(d[x][y]) cg|=clean(x,y);
        else cg=true;
        if(d[xx][yy]) cg|=clean(xx,yy);
        else cg=true;
        if(cg) down();
        
        while(cg)
        {    
            cg=false;
            for(int i=0;i<5;i++)
                for(int j=0;j<7;j++)
                    if(d[i][j] )
                        cg|=clean(i,j);
            if(cg) down();
        }
    }
    
}st;
void read(node & t)
{
    int x;
    for(int i=0;i<5;i++)
        for(int j=0;j<8;j++)
        {
            scanf("%d",&x);
            if(!x) break;
            t.d[i][j]=x;
        }
}

bool check(node a)
{
    if(a.d[0][1]==3 && a.d[2][4]==4 && a.d[4][2]==1 && a.d[4][6]==3 ) return true;
    return false;
}

struct nd
{
    node t;
    int sp;
    bool operator < (const nd & o ) const
    { return sp!=o.sp ?sp<o.sp :t<o.t ; }
};
map <nd,bool > mp;
int op[10][3],cnt;
int sm[12];
bool dfs(node nw,int stp)
{
    if(stp==step)
        if(nw.empty() ) return true;
        else return false;
    if(mp[(nd){nw,stp}]) return false;
    mp[(nd){nw,stp}]=true;
        
    memset(sm,0,sizeof(sm));
    int f=0;
    for(int i=0;i<5;i++)
        for(int j=0;j<7 && nw.d[i][j]!=0 ;j++)
        {
            sm[nw.d[i][j]]++;
            if(sm[nw.d[i][j]]==1) f++;
            else if(sm[nw.d[i][j]]==3) f--;
        }
    if(f) return false;
    
    for(int i=0;i<5;i++) //第一关键字 
    {
        for(int j=0;j<7 && nw.d[i][j] ;j++) //第二关键字 
        {
            //和右边的换/掉下去 ,自己从左边掉下去
            if(stp==4 && i==3 && j==3 && check(nw))
            {
                int aaa=1;
            } 
            if(i<4 && nw.d[i][j] !=nw.d[i+1][j] ) 
            {
                node nx=nw;
                nx.change(i,j,i+1,j);
                if(dfs(nx,stp+1))
                {
                    op[stp][0]=i,op[stp][1]=j,op[stp][2]=1;
                    return true;
                }
            }
            
            if(i>0 && !nw.d[i-1][j] )
            {
                node nx=nw;
                nx.change(i-1,j,i,j);
                if(dfs(nx,stp+1))
                {
                    op[stp][0]=i,op[stp][1]=j,op[stp][2]=-1;
                    return true;
                }
            }
        }
    }
    return false;
}

int main()
{
    scanf("%d",&step);
    read(st);
    
    if(dfs(st,0))
        for(int i=0;i<step;i++)
            printf("%d %d %d\n",op[i][0],op[i][1],op[i][2]);
    else
        printf("-1\n");
    
    return 0;
}

 

posted @ 2019-10-28 19:24  心若笺诗  阅读(109)  评论(0编辑  收藏  举报