1. 程式人生 > >noip2011 Mayan遊戲 dfs+模擬

noip2011 Mayan遊戲 dfs+模擬

程式碼能力太弱啊,調了一天。首先我bfs掛了,因為狀態太多而MLE,好像只能dfs,然後bfs改dfs過程中傻x錯誤一大堆。這道題主要是模擬比較麻煩,消除塊的情況非常複雜。剪枝的話,如果一個塊左邊有塊,就不用搜它向左移的情況,因為左邊的塊向右移會更優。剪這一個應該就可以。還有總結這幾天做題經驗,一定謹慎使用STL,刪塊的時候把要刪的座標加入佇列最後一起刪,結果用了8s,記錄了一下刪塊,結果不到1s。開始沒有意識到這個問題,一天就這樣過去了。%%%當場A掉的大神。最後希望大家打程式碼要有耐心,調個大爆搜還是挺漲姿勢的。

#include<iostream>
#include<cstdio>
#include<queue> #include<stack> #include<algorithm> using namespace std; int n; struct M{ int x[6],y[6],z[6]; int mp[9][7]; int col[12],c; int check() { int h=1; for(int i=1;i<=c;i++) if(col[i]){h=0;if(col[i]<3)return 2;} return
h; } void ans() { for(int i=0;i<n;i++) printf("%d %d %d\n",x[i]-1,7-y[i],z[i]); } void print() { for(int i=1;i<=7;i++) { for(int j=1;j<=5;j++) cout<<mp[i][j]; puts(""); } } bool
fall() { bool h=0; for(int i=6;i>=1;i--) for(int j=1;j<=5;j++) { if(!mp[i][j]) continue; int x=i; while(!mp[x+1][j]) {x++;h=1;} swap(mp[i][j],mp[x][j]); } return h; } void del() { for(int j=1;j<=7;j++) for(int i=1;i<=5;i++) { int p=mp[j][i]; if(p&&p==mp[j][i+1]&&p==mp[j][i+2]) { col[p]-=3; mp[j][i]=0; mp[j][i+1]=0; mp[j][i+2]=0; for(int x=0;x<=2;x++) { int r1=1,r2=1; while(mp[j-r1][i+x]==p) r1++; while(mp[j+r2][i+x]==p) r2++; if(r1+r2-1>=3) { for(int w=j-r1+1;w<=j+r2-1;w++) { col[mp[w][i+x]]--; mp[w][i+x]=0; } } } for(int x=3;x<=4;x++) { if(p==mp[j][i+x]) { col[mp[j][i+x]]--; mp[j][i+x]=0; int r1=1,r2=1; while(mp[j-r1][i+x]==p) r1++; while(mp[j+r2][i+x]==p) r2++; if(r1+r2-1>=3) { for(int w=j-r1+1;w<=j+r2-1;w++) { col[mp[w][i+x]]--; mp[w][i+x]=0; } } } else break; } } else if(p&&p==mp[j+1][i]&&p==mp[j+2][i]) { col[p]-=3; mp[j][i]=0; mp[j+1][i]=0; mp[j+2][i]=0; for(int x=1;x<=2;x++) { int r1=1,r2=1; while(mp[j+x][i-r1]==p) r1++; while(mp[j+x][i+r2]==p) r2++; if(r1+r2-1>=3) { for(int w=i-r1+1;w<=i+r2-1;w++) { col[mp[j+x][w]]--; mp[j+x][w]=0; } } } for(int x=3;x<=4;x++) { if(p==mp[j+x][i]) { col[mp[j+x][i]]--; mp[j+x][i]=0; int r1=1,r2=1; while(mp[j+x][i-r1]==p) r1++; while(mp[j+x][i+r2]==p) r2++; if(r1+r2-1>=3) { for(int w=i-r1+1;w<=i+r2-1;w++) { col[mp[j+x][w]]--; mp[j+x][w]=0; } } } else break; } } } if(fall()) del(); } }; M A;int ans; void dfs(int X) { if(ans) return; int p=A.check(); if(p==1&&X==n){ans=1;A.ans();return;} if(p==2) return; if(X==n)return; for(int i=1;i<=5;i++) for(int j=7;j>=1;j--) { if(!A.mp[j][i]) break; M B=A; if(i<5) { A.x[X]=i;A.y[X]=j; A.z[X]=1; swap(A.mp[j][i],A.mp[j][i+1]); A.fall();A.del(); dfs(X+1);A=B; } if(i>1&&!A.mp[j][i-1]) { A.x[X]=i;A.y[X]=j; A.z[X]=-1; swap(A.mp[j][i],A.mp[j][i-1]); A.fall();A.del(); dfs(X+1);A=B; } } } int main() { int x; scanf("%d",&n); for(int i=1;i<=5;i++) { int tot=0; while(true) { scanf("%d",&x); A.mp[7-tot][i]=x; A.c=max(A.c,x); if(!x)break; A.col[x]++; tot++; } } for(int i=1;i<=5;i++) A.mp[8][i]=23+i; for(int i=1;i<=7;i++) A.mp[i][6]=233+i; dfs(0); if(!ans) puts("-1"); return 0; }

從昨天下午就開始做這道題,晚上還是沒有做出來,GG,心情很不爽,去樓下物理搞事情,簡直interesting。其實一個人或一群人全身心投入去鑽研一個東西,真的是很愉♂快的(羨慕隔壁物理的老司機們)。