1. 程式人生 > >NOIP2011Mayan遊戲(模擬)

NOIP2011Mayan遊戲(模擬)

wap 原來 流行 遊戲界面 ase truct htm swa 剪枝

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; }

NOIP2011Mayan遊戲(模擬)