n<=30 * m<=30 的地图上,0表示墙壁,1表示可以放箱子的空地。q<=500次询问,每次问:当空地上唯一没有放箱子的空格子在(ex,ey)时,把位于(sx,sy)的箱子移动到(tx,ty)的最小步数。
Solution
一开始听说这道题很难,所以刚拿到题就开始打暴力,emmm。。。
比较。。。。。的思路是记录当前点的位置和空白点的位置,然后暴力转移。
但这个状态十分没有必要,因为我的位置能动的前提是空格在我的当前位置的旁边。
所以我们把状态变成当前点的位置和空白点在当前点的什么方位。
但转移变得困难了,因为我还需要知道从一个点到另一个点不经过某个点的最短距离。
于是就不会了,滚去看TJ。
发现不能经过的点就在当前点的旁边。
所以我们n^2*m^2*4的预处理出这个东西。
但初始状态怎么搞?不能经过的点不在起点旁边啊?
考虑暴力处理这个问题。
发现能过2333
注意判0的情况。
Code
#include#include #include #include #include #include #define R register #define mm make_pair using namespace std; const int dx[4]={0,0,-1,1}; const int dy[4]={1,-1,0,0}; struct node{ int x,y,tag; }; queue q; queue int,int> >que; int a[32][32],ex,ey,sx,sy,tx,ty,n,m,qu,dis[32][32][4],ans,mi[32][32][4][32][32],ji[5],di[32][32]; bool vis[32][32][4],visi[32][32]; inline int rd(){ int x=0;char c=getchar();while(!isdigit(c))c=getchar(); while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();} return x; } inline void BFS(int ii,int jj,int x2,int y2,int tag){ que.push(mm(ii,jj)); mi[ii][jj][tag][ii][jj]=0; while(!que.empty()){ int u1=que.front().first,u2=que.front().second;visi[u1][u2]=0;que.pop(); for(int i=0;i<4;++i){ int v1=u1+dx[i],v2=u2+dy[i]; if((v1==x2&&v2==y2)||!a[v1][v2])continue; if(mi[ii][jj][tag][v1][v2]>mi[ii][jj][tag][u1][u2]+1){ mi[ii][jj][tag][v1][v2]=mi[ii][jj][tag][u1][u2]+1; if(!visi[v1][v2]){ visi[v1][v2]=1; que.push(mm(v1,v2)); } } } } } inline void BB(int ii,int jj,int x2,int y2){ que.push(mm(ii,jj)); memset(di,0x3f,sizeof(di)); di[ii][jj]=0; while(!que.empty()){ int u1=que.front().first,u2=que.front().second;visi[u1][u2]=0;que.pop(); for(int i=0;i<4;++i){ int v1=u1+dx[i],v2=u2+dy[i]; if((v1==x2&&v2==y2)||!a[v1][v2])continue; if(di[v1][v2]>di[u1][u2]+1){ di[v1][v2]=di[u1][u2]+1; if(!visi[v1][v2]){ visi[v1][v2]=1; que.push(mm(v1,v2)); } } } } } int main(){ n=rd();m=rd();qu=rd();ji[0]=1;ji[3]=2;ji[1]=0;ji[2]=3; memset(mi,0x3f,sizeof(mi)); for(R int i=1;i<=n;++i)for(R int j=1;j<=m;++j)a[i][j]=rd(); for(R int i=1;i<=n;++i) for(R int j=1;j<=m;++j) for(R int k=0;k<4;++k)BFS(i,j,i+dx[k],j+dy[k],k); while(qu--){ ex=rd();ey=rd();sx=rd();sy=rd();tx=rd();ty=rd(); if(tx==sx&&ty==sy){ printf("0\n"); continue; } memset(dis,0x3f,sizeof(dis)); for(int i=0;i<4;++i){ int xx=sx+dx[i],yy=sy+dy[i]; BB(ex,ey,sx,sy); if(di[xx][yy]!=0x3f3f3f3f){ q.push(node{sx,sy,i}); dis[sx][sy][i]=di[xx][yy]; } } ans=0x7f7f7f7f; while(!q.empty()){ node u=q.front();q.pop();vis[u.x][u.y][u.tag]=0; if(u.x==tx&&u.y==ty){ ans=min(ans,dis[u.x][u.y][u.tag]); continue; } for(R int i=0;i<4;++i){ R int xx=u.x+dx[i],yy=u.y+dy[i]; if(!a[xx][yy])continue; int x=u.x+dx[u.tag],y=u.y+dy[u.tag],z=mi[x][y][ji[u.tag]][xx][yy]+1; if(dis[xx][yy][ji[i]]>dis[u.x][u.y][u.tag]+z){ dis[xx][yy][ji[i]]=dis[u.x][u.y][u.tag]+z; if(!vis[xx][yy][ji[i]]){ vis[xx][yy][ji[i]]=1; q.push(node{xx,yy,ji[i]}); } } } } if(ans!=0x7f7f7f7f)printf("%d\n",ans); else printf("-1\n"); } return 0; }