POJ 1475: 推箱子

来源:互联网 发布:怎样在淘宝整点抢衣服 编辑:程序博客网 时间:2024/05/29 04:54

表示被毒瘤题吓到了!(我要回家)

暴力出奇迹,骗分过样例。数学先打表,DP看运气。穷举TLE,递推UKE。模拟MLE,贪心还CE。想要骗到分,就要有方法。图论背模板,数论背公式。动规背方程,高精背代码。如果都没背,干脆输样例。模拟定想全,动规定找对。贪心定证明,二分L M+1。

vis[i][j][k] 表示从(i,j) 的经过的k方向 有没有 走过!
因为如果普通BFS的vis是没有用的!
such as this

8 8#########.....T##..S...####B#####......##......##......#########

还要就是要知道,不一定是箱子的最短路会引起答案的正确,就是说箱子是找一条合适的路,而不是最短的路,所以不能在BFS完箱子之后,再枚举人的路径!,于是就是在BFS箱子的路径的时候顺便判断一下人的路径,那么在用一个struct 储存一个string 最后输出!

#pragma GCC optimize(3)#include <iostream>#include <stdio.h>#include <algorithm>#include <cstring>#include <queue>#include <string>#define N 25using namespace std;int n,m,sx,sy,bx,by,ex,ey,fuck,vis[N][N][4],to[N][N];int dx[4]={-1,1,0,0};int dy[4]={0,0,-1,1};char how[4]={'N','S','W','E'},sm[4]={'n','s','w','e'}; // the dirctionchar s[N][N];// x,y : people   tox,toy : box!struct node{int x,y,tox,toy;string ans;}now,nxt,pre;queue<node> G,S;string temp;inline bool check(int x,int y){if(x>=1&&x<=n&&y>=1&&y<=m&&s[x][y]!='#') return 1;return 0;}bool Find(int startx,int starty,int tox,int toy,int canx,int cany){    temp="";    memset(to,0,sizeof to);    while(!S.empty()) S.pop();    node bb;    bb.x=startx,bb.y=starty; S.push(bb);    while(!S.empty())    {        node last=S.front(); S.pop();        if(last.x==tox&&last.y==toy) {temp=last.ans;return true;}        for(int i=0;i<4;i++)        {            node yy=last; yy.x+=dx[i];yy.y+=dy[i];            if(!check(yy.x,yy.y) || (yy.x==canx&&yy.y==cany) || to[yy.x][yy.y]) continue;            to[yy.x][yy.y]=1;            yy.ans=last.ans+sm[i];            S.push(yy);        }    }    return false;}string BFS_BOX(){    now.x=sx,now.y=sy;  // start == perxon x ,y    now.tox=bx,now.toy=by; // where box is  == box x,y    now.ans="";    while(!G.empty()) G.pop();    G.push(now);    while(!G.empty())    {        now=G.front(); G.pop();        if(now.tox==ex && now.toy==ey)           return now.ans;        for(int i=0;i<4;i++)        {            // this means can people reach the box's back so that the box can move            // we just need to let the box move and judge whether people can reach there!            nxt=now;            nxt.tox+=dx[i],nxt.toy+=dy[i];            nxt.x=now.tox,nxt.y=now.toy;            if(!check(nxt.tox,nxt.toy) || vis[nxt.tox][nxt.toy][i]) continue;            if(i==0)        {if(Find(now.x,now.y,now.tox+1,now.toy,now.tox,now.toy)) nxt.ans+=temp;else continue;}            if(i==1)        {if(Find(now.x,now.y,now.tox-1,now.toy,now.tox,now.toy)) nxt.ans+=temp;else continue;}            if(i==2)        {if(Find(now.x,now.y,now.tox,now.toy+1,now.tox,now.toy)) nxt.ans+=temp;else continue;}            if(i==3)        {if(Find(now.x,now.y,now.tox,now.toy-1,now.tox,now.toy)) nxt.ans+=temp;else continue;}            vis[nxt.tox][nxt.toy][i]=1;            nxt.ans+=how[i];            G.push(nxt);        }    }    return "Impossible.";}int main(){    while(~scanf("%d%d",&n,&m) &&n&&m)    {        memset(vis,0,sizeof vis);        for(int i=1;i<=n;i++)            for(int j=1;j<=m;j++)            {                cin>>s[i][j];                if(s[i][j]=='S') sx=i,sy=j;                if(s[i][j]=='B') bx=i,by=j;                if(s[i][j]=='T') ex=i,ey=j;            }        printf("Maze #%d\n",++fuck);        cout<<BFS_BOX()<<endl;        puts("");    }    return 0;}