P1312 Mayan遊戲
阿新 • • 發佈:2018-12-16
辣雞模擬題!就是暴力亂搞,然後一堆小細節要注意qwq
把某谷的資料點騙完了終於過了嘔
然後是剪枝的四個原則:(轉載)
(1)交換兩個顏色相同的塊沒有意義
(2)一個塊的左邊是非空塊時不需要考慮左移,因為會和之前的塊右移重複,即只有當左塊為空時才左移
(3)根據題目優先度的排序,可以知道,右移優先於左移,所以在dfs時先考慮右移
(4)如果有一種顏色當前的塊數目x滿足1<=x<=2,則此情況不合法
然後細心打一下就好啦....
#include <iostream> #include <algorithm> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <ctime> #define maxn 15 using namespace std; bool flag,tag[maxn][maxn]; int n,a[maxn][maxn],cnt[maxn+5],ans[maxn][3]; int read() { int xx=0,kk=1;char ch=' '; while(!isdigit(ch)){ch=getchar();if(ch=='-')kk=-1;} while(isdigit(ch)){xx=xx*10+ch-'0';ch=getchar();} return kk*xx; } bool find() { bool flag=false; memset(tag,false,sizeof(tag)); for(int i=1;i<=5;++i) for(int j=1;j<=7;++j) { if(!a[i][j]) continue; 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]=true,flag=true; 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]=true,flag=true; } return flag; } void del() { for(int i=1;i<=5;++i) { int low=0,sum=0; for(int j=1;j<=7;++j) { if(!low&&tag[i][j]) low=j; if(tag[i][j]) sum++; } for(int j=1;j<=7;++j) if(j>=low) a[i][j]=a[i][j+sum]; } } bool success() { for(int i=1;i<=5;++i) for(int j=1;j<=7;++j) if(a[i][j]) return false; return true; } bool check() { memset(cnt,0,sizeof(cnt)); for(int i=1;i<=5;++i) for(int j=1;j<=7;++j) if(a[i][j]) cnt[a[i][j]]++; for(int i=1;i<=10;++i) if(cnt[i]&&cnt[i]<3) return false; return true; } bool dfs(int x,int y,int dep,int dir) { if(dep<0||x+dir<1||x+dir>5) return false; if(a[x+dir][y]==a[x][y]) return false; if(dir==-1&&a[x+dir][y]) return false; if(!check()) return false; int tmp[maxn][maxn],len=0; while(!a[x+dir][y-len]&&len<y) len++; if(len) { swap(a[x][y],a[x+dir][y-len+1]); for(int i=y;i<=7;++i) a[x][i]=a[x][i+1]; } else swap(a[x][y],a[x+dir][y]); while(find()) del(); memcpy(tmp,a,sizeof(tmp)); if(success()) { flag=true; ans[dep][0]=x,ans[dep][1]=y,ans[dep][2]=dir; return true; } for(int i=1;i<=5;++i) for(int j=1;j<=7;++j) { if(!a[i][j]) continue; memcpy(a,tmp,sizeof(a)); if(dfs(i,j,dep-1,1)) { ans[dep][0]=x,ans[dep][1]=y,ans[dep][2]=dir; return true; } memcpy(a,tmp,sizeof(a)); if(dfs(i,j,dep-1,-1)) { ans[dep][0]=x,ans[dep][1]=y,ans[dep][2]=dir; return true; } memcpy(a,tmp,sizeof(a)); } return false; } int main() { n=read(); int tmp[maxn][maxn]; for(int i=1;i<=5;++i) for(int j=1;j<=8;++j) { a[i][j]=read(); if(!a[i][j]) break; } memcpy(tmp,a,sizeof(a)); for(int i=1;i<=5;++i) for(int j=1;j<=7;++j) { if(!a[i][j]) continue; memcpy(a,tmp,sizeof(tmp)); if(dfs(i,j,n-1,1)) break; memcpy(a,tmp,sizeof(tmp)); if(dfs(i,j,n-1,-1)) break; } if(flag) { for(int i=n-1;i>=0;--i) if(ans[i][0]&&ans[i][1]) printf("%d %d %d\n",ans[i][0]-1,ans[i][1]-1,ans[i][2]); } else puts("-1"); return 0; }