• NOIP2011Mayan游戏(模拟)


    Mayan puzzle是最近流行起来的一个游戏。游戏界面是一个77 行 imes 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
    ",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;
    }
  • 相关阅读:
    RPMBUILD源码打包资源汇总(转)
    grep命令:查看配置文件未注释行(转)
    数据结构实验之查找三:树的种类统计(SDUT 3375)
    数据结构实验之查找三:树的种类统计(SDUT 3375)
    数据结构实验之查找四:二分查找(SDUT 3376)
    数据结构实验之查找五:平方之哈希表 (SDUT 3377)
    数据结构实验之查找一:二叉排序树 (SDUT 3373)
    python 正则表达式
    python #!/usr/bin/python 的作用
    欢迎使用CSDN的markdown编辑器
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/9622324.html
Copyright © 2020-2023  润新知