POJ 2049题解

这是一篇关于POJ 2049题目的解题报告。文章介绍了Nemo被困在迷宫中,其father Marlin需要通过最少的门来寻找Nemo的问题。题目分析提到虽然问题看似迷宫,但关键在于已访问的格子可以再次访问,且这是在求解最优路径的前提下。文章并未给出详细的解题代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目来源:http://poj.org/problem?id=2049

题目描述:

Nemo被困在一个迷宫中,他的father Marlin准备去救他,迷宫有很多门,Marlin只能从门中过,问Marlin最少需要经过多少门才能找到Nemo.


题目分析:

题目描述很容易让人想起迷宫的题,其实基本思想是一样的,但是有一点比较重要就是:一个格子被访问过之后还能再被访问。但是这是满足最优前提下的。具体看代码吧


代码实现:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef struct
{
    int x,y;
} Point;
int mat[201][201][2];
int step[201][201];

Point Queue[200000];
int main()
{
    int n,m;
    int x,y,dir,len;
    double posX,posY;
    while(scanf("%d%d",&n,&m))
    {
        if(n== -1 && m == -1)
            return 0;
        memset(mat,-1,sizeof(mat));
        for(int i = 0; i<=200; i++)
            for(int j = 0; j<=200; j++)
                step[i][j] = 99999999;
        for(int i = 0; i<n; i++)
        {
            scanf("%d%d%d%d",&x,&y,&dir,&len);
            if(dir == 0)
            {
                for(int j = x ; j < x + len; j++)
                {
                    mat[j][y][0] = 0;
                }
            }
            else
            {
                for(int j = y ; j < y + len; j++)
                {
                    mat[x][j][1] = 0;
                }
            }
        }
        for(int i = 0; i<m; i++)
        {
            scanf("%d%d%d",&x,&y,&dir);
            mat[x][y][dir] = 1;
        }
        cin>>posX>>posY;
        if(posX<=0||posX>199||posY<=0||posY>199)
            cout<<"0\n";
        else
        {
            int front,rear;
            front = rear = -1;
            Point p;
            rear++;
            int X = (int)posX;
            int Y = (int)posY;
            p.x = X;
            p.y = Y;
            step[X][Y] = 0;
            Queue[rear] = p;
            int ans = 99999999;
            bool f = false;
            while(front<=rear)
            {
                front++;
                Point pp = Queue[front];
                if(pp.y - 1 >= 0)
                {
                    if(mat[pp.x][pp.y][0] == 1 || mat[pp.x][pp.y][0] == -1)
                    {
                        p.x = pp.x;
                        p.y = pp.y - 1;
                        int l;
                        if(mat[pp.x][pp.y][0] == -1)
                            l = step[pp.x][pp.y];
                        else
                            l = step[pp.x][pp.y] + 1;
                        if(l < step[p.x][p.y])
                        {
                            rear++;
                            step[p.x][p.y] = l;
                            Queue[rear] = p;
                        }
                    }
                }
                if(pp.x - 1 >= 0)
                {
                    if(mat[pp.x][pp.y][1] == 1||mat[pp.x][pp.y][1] == -1)
                    {
                        p.x = pp.x - 1;
                        p.y = pp.y;
                        int l;
                        if(mat[pp.x][pp.y][1] == -1)
                            l = step[pp.x][pp.y];
                        else
                            l = step[pp.x][pp.y] + 1;
                        if(l < step[p.x][p.y])
                        {
                            rear++;
                            step[p.x][p.y] = l;
                            Queue[rear] = p;
                        }
                    }
                }
                if(pp.y + 1 <= 199)
                {
                    if(mat[pp.x][pp.y + 1][0] == 1 || mat[pp.x][pp.y + 1][0] == -1)
                    {
                        p.x = pp.x;
                        p.y = pp.y + 1;
                        int l;
                        if(mat[pp.x][pp.y + 1][0] == 1)
                            l = step[pp.x][pp.y] + 1;
                        else
                            l = step[pp.x][pp.y];
                        if(l < step[p.x][p.y])
                        {
                            rear++;
                            step[p.x][p.y] = l;
                            Queue[rear] = p;
                        }
                    }
                }
                if(pp.x + 1 <= 199)
                {
                    if(mat[pp.x + 1][pp.y][1] == 1 || mat[pp.x + 1][pp.y][1] == -1)
                    {
                        p.x = pp.x + 1;
                        p.y = pp.y;
                        int l;
                        if(mat[pp.x + 1][pp.y][1] == 1)
                            l = step[pp.x][pp.y] + 1;
                        else
                            l = step[pp.x][pp.y];
                        //cout<<l<<' '<<step[p.x][p.y]<<endl;
                        if(l < step[p.x][p.y])
                        {
                            //cout<<"!!!\n";
                            rear++;
                            step[p.x][p.y] = l;
                            Queue[rear] = p;
                        }
                    }
                }
            }
            //cout<<step[0][1]<<endl;
            if(step[0][0]!=99999999)
                cout<<step[0][0]<<endl;
            else
                cout<<"-1\n";
        }
        //cout<<"!!!!\n";
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值