1. 程式人生 > 實用技巧 >題解 洛谷P2199 【最後的迷宮】

題解 洛谷P2199 【最後的迷宮】

\(Sol\)

這道題我們可以用\(BFS\)解決!
我們先通過一個\(BFS\)預處理出\(Harry\)走到每一個格子所需的最短時間。
然後,我們從獎盃開始向八個方向展開,找\(Harry\)走到這些能夠直接看到獎盃的最短時間。
注意:遇到牆就不能繼續擴充套件了,視線是不能穿牆的!

\(Code\)

#include<bits/stdc++.h>
using namespace std;
struct Struct
{
    int X;
    int Y;
};
string Map[16385];
vector<int>V[16385];
queue<Struct>Queue;
int Dir[8][2]={1,0,0,1,-1,0,0,-1,1,1,-1,-1,1,-1,-1,1};
int main(void)
{
    register int Line,Column;
    cin>>Line>>Column;
    register int i,j;
    for(i=1;i<=Line;i++)
    {
    	cin>>Map[i];
    	Map[i]="@"+Map[i];
    	V[i].resize(Column+1);
	}
    int Sx,Sy,Ex,Ey;
    while(cin>>Ex>>Ey>>Sx>>Sy)
    {
        if(!Ex&&!Ey&&!Sx&&!Sy)
        {
            break;
        }
        for(i=1;i<=Line;i++)
        {
        	for(j=1;j<=Column;j++)
        	{
        		V[i][j]=0x3f3f3f3f;
			}
		}
        V[Sx][Sy]=0;
        Queue.push(Struct{Sx,Sy});
        while(!Queue.empty())
        {
            register Struct Top;
            Top=Queue.front();
            Queue.pop();
            for(i=0;i<4;i++)
            {
                register int Dx,Dy;
                Dx=Top.X+Dir[i][0];
                Dy=Top.Y+Dir[i][1];
                if(Dx>0&&Dy>0&&Dx<=Line&&Dy<=Column&&V[Dx][Dy]==0x3f3f3f3f&&Map[Dx][Dy]=='O')
                {
                	V[Dx][Dy]=V[Top.X][Top.Y]+1;
                    Queue.push(Struct{Dx,Dy});
                }
            }
        }
		register int Ans;
        Ans=V[Ex][Ey];
        for(i=0;i<8;i++)
        {
        	register int Dx,Dy;
        	Dx=Ex+Dir[i][0];
        	Dy=Ey+Dir[i][1];
        	while(Dx>0&&Dy>0&&Dx<=Line&&Dy<=Column&&Map[Dx][Dy]=='O')
        	{
        		Ans=min(Ans,V[Dx][Dy]);
        		Dx=Dx+Dir[i][0];
        		Dy=Dy+Dir[i][1];
			}
		}
		if(Ans==0x3f3f3f3f)
		{
			cout<<"Poor Harry"<<endl;
			continue;
		}
		cout<<Ans<<endl;
    }
    return 0;
}