[COGS 622] [NOIP2011] 玛雅游戏 模拟

原文链接: http://www.cnblogs.com/TSHugh/p/7248191.html

整个模拟的关键除了打出来就是一个剪枝:对于两个左右相邻的块你不用再走←,因为走→是等效的

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#define r register
using namespace std;
int f[20][20][20];
int s[20][20];
bool die[20][20];
int n;
bool god;
inline void Init()
{
    scanf("%d",&n);
    for(int i=1,x;i<=5;i++)
      while(1)
      {
        scanf("%d",&x);
        if(x==0)break;
        f[0][i][++f[0][i][0]]=x;
      }
}
void arrange(int h,int x,int y,int t)
{ 
     s[h][1]=x;
     s[h][2]=y;
     s[h][3]=t; 
     memcpy(f[h],f[h-1],sizeof(f[h]));
     f[h][x][y]^=f[h][x+t][y]^=f[h][x][y]^=f[h][x+t][y];
     if(!f[h][x][y])++f[h][x+t][0],--f[h][x][0];
     if(f[h][x][y]==0&&f[h][x][y+1]!=0)
     {
       r int j=y+1;
       while(f[h][x][j]!=0)
        f[h][x][j-1]^=f[h][x][j]^=f[h][x][j-1]^=f[h][x][j],++j; 
     } 
     if(f[h][x+t][y-1]==0)
     {
       r int j=y-1;
       while(f[h][x+t][j]==0)
         f[h][x+t][j]^=f[h][x+t][j+1]^=f[h][x+t][j]^=f[h][x+t][j+1],--j;
     } 
     r int get;
     do
     {
       get=0;
       for(r int i=1;i<=5;++i)
        for(r int j=1;j<=f[h][i][0];++j)
        {
           r int k=0;
           while(f[h][i][j]==f[h][i][j+k])++k;
           if(k>=3)
           {
             for(int l=0;l<k;++l)
              die[i][j+l]=1;
           }
           j+=k-1;
        }
       for(r int i=1;i<=7;++i)
        for(r int j=1;j<=5;++j)
        {
           if(f[h][j][i]==0)continue;
           r int k=0;
           while(f[h][j][i]==f[h][j+k][i])++k;
           if(k>=3)
           {
             for(int l=0;l<k;l++)
              die[j+l][i]=1;
           }
           j+=k-1;
        }
        for(r int i=1;i<=5;++i)
          for(r int j=1;j<=f[h][i][0];++j)
           if(die[i][j])
            f[h][i][j]=0,die[i][j]=0;
        for(r int i=1;i<=5;++i)
        {
          r int k=0;
          for(r int j=1;j<=f[h][i][0];++j)
           if(f[h][i][j])f[h][i][++k]=f[h][i][j];
           else ++get;
          for(r int j=k+1;j<=f[h][i][0];++j)f[h][i][j]=0;
          f[h][i][0]=k;
        }
     }while(get);
}
void dfs(int x)
{
    if(x==n)
    {
      r int sum=0;
      for(r int i=1;i<=5;++i)sum+=f[x][i][0];
      if(sum==0)god=1;
      return;
    }
    for(r int i=1;i<=5;i++)
     for(r int j=1;j<=f[x][i][0];j++)
     {
       if(i!=5)
       {
         arrange(x+1,i,j,1);
         dfs(x+1);
         if(god)return;
       }
       if(i!=1&&f[x][i-1][j]==0)
       {
         arrange(x+1,i,j,-1);
         dfs(x+1);
         if(god)return;
       }
     }
}
inline void work()
{
    dfs(0);
    if(god)
    {
      for(int i=1;i<=n;i++)
       printf("%d %d %d\n",s[i][1]-1,s[i][2]-1,s[i][3]);
    }
    else
     printf("-1");
}
int main()
{
    Init();
    work();
    return 0;
}

转载于:https://www.cnblogs.com/TSHugh/p/7248191.html

猜你喜欢

转载自blog.csdn.net/weixin_30851867/article/details/94800947