noip2011 Mayan遊戲 dfs+模擬
阿新 • • 發佈:2019-01-08
程式碼能力太弱啊,調了一天。首先我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。其實一個人或一群人全身心投入去鑽研一個東西,真的是很愉♂快的(羨慕隔壁物理的老司機們)。