代码能力太弱啊,调了一天。首先我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。其实一个人或一群人全身心投入去钻研一个东西,真的是很愉♂快的(羡慕隔壁物理的老司机们)。