zoukankan      html  css  js  c++  java
  • AcWing174 推箱子

    题目链接

    这个小人,不讲武德,总是围着箱子绕一圈再推。。然后因为这个调了三四个小时。。

    双 BFS。搜索状态表示为 ((x,y,d)),表示箱子坐标是 ((x,y)),小人在箱子的 (d) 方向。外面的 BFS 算箱子路径,里面的 BFS 算小人路径。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<string>
    using namespace std;
    const int N=20;
    const char dir[4]={'n','s','w','e'},Dir[4]={'N','S','W','E'};
    const int nxt[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
    char s[N+10][N+10];
    int n,m;
    bool vis1[N+10][N+10]; 
    struct man
    {
    	int x,y;
    	string s;
    	man() 
    	{
    		x=y=0;
    		s="";
    	}
    	man(int xx,int yy,string ss)
    	{
    		x=xx;
    		y=yy;
    		s=ss;
    	}
    };
    // (box_x, box_y) can't visit
    string expand(int bx,int by,int stx,int sty,int edx,int edy)
    {
    	if(stx==edx && sty==edy) return "";
    	memset(vis1,false,sizeof(vis1));
    	queue<man> que;
    	vis1[bx][by]=1;
    	vis1[stx][sty]=1;
    	que.push(man(stx,sty,""));
    	while(!que.empty())
    	{
    		man head=que.front();
    		que.pop();
    		if(head.x==edx && head.y==edy) return head.s;
    		for(int i=0;i<4;i++) 
    		{
    			int xx=head.x+nxt[i][0],yy=head.y+nxt[i][1];
    			if(xx<1 || xx>n || yy<1 || yy>m) continue;
    			if(s[xx][yy]=='#' || vis1[xx][yy]) continue; 
    			vis1[xx][yy]=1;
    			que.push(man(xx,yy,head.s+dir[i]));
    		}
    	}
    	return "Fail";
    }
    int stx,sty,edx,edy,px,py;
    struct box
    {
    	int x,y,dir,len;
    	string s;
    	box()
    	{
    		len=0;
    		x=y;
    		dir=-1;
    		s="";
    	}
    	box(int xx,int yy,int ddir,string ss,int llen)
    	{
    		len=llen;
    		x=xx;
    		y=yy;
    		dir=ddir;
    		s=ss;
    	}
    };
    int f_box[N+10][N+10][4],f_man[N+10][N+10][4];
    string bfs()
    {
    	memset(f_box,0x3f,sizeof(f_box));
    	memset(f_man,0x3f,sizeof(f_man));
    	queue<box> que;
    	for(int i=0;i<4;i++)
    	{
    		int xx=stx-nxt[i][0],yy=sty-nxt[i][1];
    		string tmp=expand(stx,sty,px,py,xx,yy);
    		if(tmp[0]=='F') continue;
    		que.push(box(stx,sty,i,tmp,0));
    		f_box[stx][sty][i]=0;
    		f_man[stx][sty][i]=min(f_man[stx][sty][i],(int)tmp.length());
    	}
    	int l=0x7fffffff,l1=0x7fffffff;
    	string ans="Impossible.";
    	while(!que.empty())
    	{
    		box head=que.front();
    		que.pop();
    		if(head.x==edx && head.y==edy) 
    		{
    			if(head.len<l)
    			{
    				l=head.len;
    				ans=head.s;
    				l1=head.s.length();
    			} 
    			else if(head.len==l)
    			{
    				if((int)head.s.length()<l1)
    				{
    					l1=(int)head.s.length();
    					ans=head.s;
    				}
    			}
    			continue;
    		} 
    		for(int i=0;i<4;i++)
    		{
    			int xx=head.x+nxt[i][0],yy=head.y+nxt[i][1];
    			if(xx<1 || xx>n || yy<1 || yy>m) continue;
    			if(s[xx][yy]=='#') continue;
    			string tmp=
    			expand(head.x,head.y,head.x-nxt[head.dir][0],
    			head.y-nxt[head.dir][1],head.x-nxt[i][0],
    			head.y-nxt[i][1]);
    			if(tmp[0]=='F') continue;
    			if(head.len+1>f_box[xx][yy][i]) continue;
    			if(head.len+1==f_box[xx][yy][i])
    			{
    				string tmp1=head.s+tmp+Dir[i];
    				if((int)tmp.length()>f_man[xx][yy][i]) continue;
    				else f_man[xx][yy][i]=min(f_man[xx][yy][i],(int)tmp.length());
    			}
    			else
    			{
    				string tmp1=head.s+tmp+Dir[i];
    				f_box[xx][yy][i]=head.len+1;
    				f_man[xx][yy][i]=(int)tmp1.length();
    			}
    			que.push(box(xx,yy,i,head.s+tmp+Dir[i],head.len+1));
    		}
    	}
    	return ans;
    }
    int main()
    {
    	ios::sync_with_stdio(false);
    	int Case=0;
    	while(1)
    	{
    		cin>>n>>m;
    		if(n==0 && m==0) break;
    		for(int i=1;i<=n;i++) cin>>(s[i]+1);
    		for(int i=1;i<=n;i++)
    		{
    			for(int j=1;j<=m;j++)
    			{
    				if(s[i][j]=='B')
    				{
    					stx=i;
    					sty=j;
    				}
    				else if(s[i][j]=='S')
    				{
    					px=i;
    					py=j;
    				}
    				else if(s[i][j]=='T')
    				{
    					edx=i;
    					edy=j;
    				}
    			}
    		}
    		cout<<"Maze #"<<++Case<<endl<<bfs()<<endl<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    Go标准库之tar
    redis必知必会
    GORM CRUD指南
    GORM入门指南
    MUI中tap点击事件点击一次连续申请两次
    Go代码启动默认浏览器
    Go实现JWT
    Go Micro
    protobuf初识
    英语作文
  • 原文地址:https://www.cnblogs.com/juruo-zzt/p/14048222.html
Copyright © 2011-2022 走看看