[DFS && BFS]poj3083

題意:
給出起點和終點,問分別靠着牆往左走,往右走,直接最短路分別是多少? #代表不能走,‘.’代表能走,S是起點,E是終點。
Sample Input

2
8 8

#

……

.####.

.####.

.####.

.####.

…#..

S#E

9 5

#

.#.#.#.

S…….E

.#.#.#.

#

Sample Output

37 5 5
17 17 9

分析:
這道題的主要難點就是如何選擇靠右走與靠左走。在格子裏如何辨別方向呢?
那這就需要人爲的規定方向了。
0
1 current 3
2
比如現在,current代表現在的位置,上、左、下、右 分別用0,1,2,3表示。
那麼如果是靠右走,加入自己剛從3的方向走過來,那此時自己是面朝3的,那麼這個時候的右邊是2,那麼優先2走,如果走不通就一次向左轉,所以3的方向順序就是2301 ,同理0的方向順序就是3012 。。。
找到這個規律就好了。向左也是一樣的道理。另外審題要發現靠左右走的時候可以走重複的地方。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#define read freopen("q.in","r",stdin)
#define LL long long
#define maxn 100
using namespace std;
string mp[maxn];
int dx[]={-1,0,1,0};
int dy[]={0,-1,0,1};
int vis[maxn][maxn];
int n,m;
int si,sj,ei,ej;
int l,r,res,flag;
struct Node
{
    int x,y,d; 
}node[maxn];
void  rdfs(int x,int y,int d,int dis)
{
//  cout<<x<<" "<<y<<" "<<d<<endl;
   if(mp[x][y]=='E') 
   {
        r=dis;
        flag=1;
        return ;
  }

    int i,j;
    d=(d+3)%4;
    for(i=0;i<4;i++)
    {

        int t=(d+i)%4;
        //  cout<<t<<" ";
        int tx=x+dx[t];
        int ty=y+dy[t];
        if(tx>=0 && tx<n && ty>=0 && ty<m && mp[tx][ty]!='#')
        {
            rdfs(tx,ty,t,dis+1);
            if(flag)return ;
        }
    }
//  cout<<endl;
}

void  ldfs(int x,int y,int d,int dis)
{
//  cout<<x<<" "<<y<<" "<<d<<endl;
   if(mp[x][y]=='E') 
   {
        l=dis;
        flag=1;
        return ;
  }

    int i,j;
    d=(d+1)%4;
    for(i=0;i<4;i++)
    {

        int t=(d-i+4)%4;
        //  cout<<t<<" ";
        int tx=x+dx[t];
        int ty=y+dy[t];
        if(tx>=0 && tx<n && ty>=0 && ty<m && mp[tx][ty]!='#')
        {
            ldfs(tx,ty,t,dis+1);
            if(flag)return ;
        }
    }
//  cout<<endl;
}

void  bfs()
{   
    int i,j;
    Node a;
    a.x=si;a.y=sj;a.d=1;
    queue<Node> q;

    q.push(a);
    while(!q.empty())
    {
        Node b=q.front();
        q.pop();
        for(i=0;i<4;i++)
        {
            int tx=b.x+dx[i];
            int ty=b.y+dy[i];

            if(tx>=0 && tx<n && ty>=0 && ty<m && mp[tx][ty]!='#')
            {
                if(mp[tx][ty]=='E')
                {
                    res=b.d+1;
                    return ;
                }
                mp[tx][ty]='#';
                Node c;
                c.x=tx;
                c.y=ty;
                c.d=b.d+1;
                q.push(c);
            }
        }
    }
}


int main()
{
//  read;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int i,j,d;
        scanf("%d%d",&m,&n);
        for(i=0;i<n;i++)
        {
            cin>>mp[i];
            for(j=0;j<m;j++)
            {
                if(mp[i][j]=='S')
                {
                    si=i;sj=j;
                    if(i==0)d=2;
                    else if(j==0)d=3;
                    else if(i==m)d=0;
                    else if(j==m)d=1;
                }
            }
        }
        l=r=0;
        res=maxn*maxn;
        flag=0;
        rdfs(si,sj,d,1);
        flag=0;
        ldfs(si,sj,d,1);
        bfs();
        cout<<l<<" "<<r<<" "<<res<<endl;


    }   
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章