NOIP2011Mayan游戏(模拟)

Mayan puzzle是最近流行起来的一个游戏。游戏界面是一个77 行\times 5×5列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上。游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下:

1 、每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见输入输出样例说明中的图6到图7);如果目标位置上没有方块,那么被拖动的方块将从原来的竖列中抽出,并从目标位置上掉落。

Solution

注意到n非常小,所以直接暴力就好,枚举格子,先枚举向右移动,在向左移动。

有一个小剪枝,向左移动时要移动到空的位置,如果不是,那就不是最优解(右边可以动过来)。

注意读入!!!!

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define R register
using namespace std;
int a[10][10],n,tot,bul[12];
bool tag[10][10];
struct node{
    int x,y,tag;
}ji[8];
inline void print(){
    for(int i=1;i<=7;++i){
        for(int j=1;j<=5;++j)cout<<a[i][j]<<" ";
        cout<<endl;
    }
    cout<<endl;
}
inline bool isempty(){
    for(R int i=7;i>=1;--i)
      for(R int j=1;j<=5;++j)
        if(a[i][j])return 0;
    return 1;
}
inline bool isk(){
    bool p=0;
    memset(tag,0,sizeof(tag));
    for(R int j=1;j<=5;++j)
      for(R int i=7;i>=1;--i)if(a[i][j]){
          if(a[i][j]==a[i][j+1]&&a[i][j]==a[i][j-1])tag[i][j]=tag[i][j-1]=tag[i][j+1]=1,p=1;
          if(a[i][j]==a[i-1][j]&&a[i][j]==a[i+1][j])tag[i][j]=tag[i-1][j]=tag[i+1][j]=1,p=1;
      }
      return p;
}
inline void gan(){
    for(R int i=6;i>=1;--i)
        for(R int j=1;j<=5;++j)
          if(a[i][j]&&(!a[i+1][j])){
              int pos=i;
              while(pos!=7&&a[pos][j]&&(!a[pos+1][j]))swap(a[pos][j],a[pos+1][j]),pos++;
          } 
    while(isk()){
        for(R int j=1;j<=5;++j)
          for(R int i=7;i>=1;--i)if(tag[i][j])bul[a[i][j]]--,a[i][j]=0;
        for(R int i=6;i>=1;--i)
         for(R int j=1;j<=5;++j)
          if(a[i][j]&&(!a[i+1][j])){
              int pos=i;
              while(pos!=7&&a[pos][j]&&(!a[pos+1][j]))swap(a[pos][j],a[pos+1][j]),pos++;
          } 
    }
}
void dfs(int x){
    if(isempty()){
        for(R int i=1;i<=tot;++i)printf("%d %d %d\n",ji[i].x,ji[i].y,ji[i].tag);
        exit(0);
    }
    if(x>n)return;
//    for(R int i=1;i<=10;++i)if(bul[i]==1||bul[i]==2)return;
    int b[10][10],mp[12];
    for(int i=1;i<=10;++i)mp[i]=bul[i];
    for(R int i=1;i<=7;++i)for(R int j=1;j<=5;++j)b[i][j]=a[i][j];
    for(R int j=1;j<=5;++j) 
      for(R int i=7;i>=1;--i)
      if(a[i][j]){
            if(a[i][j]!=a[i][j+1]&&j<5){
            swap(a[i][j],a[i][j+1]);
            ji[++tot]=node{j-1,7-i,1}; 
            gan(); 
            dfs(x+1);
            tot--;
            for(R int i=1;i<=7;++i)for(R int j=1;j<=5;++j)a[i][j]=b[i][j];
            for(R int i=1;i<=10;++i)bul[i]=mp[i];
          }
          if(!a[i][j-1]&&j>1){
            swap(a[i][j],a[i][j-1]);
            ji[++tot]=node{j-1,7-i,-1};
            gan();
            dfs(x+1);
            tot--;
            for(R int i=1;i<=7;++i)for(R int j=1;j<=5;++j)a[i][j]=b[i][j];
            for(R int i=1;i<=10;++i)bul[i]=mp[i];
          }
      } 
}
int main(){
    scanf("%d",&n);
    for(R int i=1;i<=5;++i)
      for(R int j=7;j>=0;--j){
        scanf("%d",&a[j][i]);
        if(!a[j][i])break;
        bul[a[j][i]]++;
     }
    dfs(1); 
    cout<<-1;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ZH-comld/p/9622324.html