POJ3669——Meteor Shower(BFS)

题目链接

        此题的意思让我难受,因为描述的很不清晰,而且数据也有问题,首先大致题意就是在一个地方会陨落流星,然后陨落的地方在坐标系的第一象限,当陨石砸中一个点,其不但会破坏被砸中点,还会破坏以被砸中点为中心的上下左右一共5个点,且它们砸落的时间不一,题目的输入就是第一行给定要砸多少陨石,然后接下来就是描述陨石砸落坐标和砸落时间,然后你会从坐标原点出发去寻找一个陨石砸不到的位置,你所能到的点只能是陨石还没破坏的点,你每移动一次耗时一个单位时间,问找到最短安全位置的步数,如果找不到输出-1.

       此题——我 TM  Runtime Error 了8次再见,都怪自己蠢,搜索bfs时判了访问点是否越界,但输入却没判,然后一直在怀疑是自己搜索越的界,还是队友帮忙看来的。。。。我的思路就是起先全图赋值-1,然后输入陨石坠落点时,将该点赋值,负的值就是陨石砸落时间,并将其四周四个点也赋值,当某个被破坏点被多次破坏时,赋值最早破坏的时间,然后从原点开始搜索,每移一步,步数加1,当访问点为-1(表示不会被破坏)或访问点值比步数大(表示现在还没被破坏),表示可以访问,然后对访问点为-1就直接终止搜索,返回步数。

        此题的坑还不少,首先题目说好的第一象限,结果数据陨石砸到了坐标轴上,而且说好的范围是[0,300],结果数据过了300,,还有就是访问过的点要标记一下,不要再次访问,貌似多次重复访问会TL。



#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>

using namespace std;

int mov1[4]= {0,1,0,-1};
int mov2[4]= {1,0,-1,0};

struct node
{
    int x;
    int y;
    int num;
    node()
    {
        x=0;
        y=0;
        num=0;
    }
    node(int a,int b,int c)
    {
        x=a;
        y=b;
        num=c;
    }
};

int mp[505][505]= {0};
bool vis[505][505]= {0};
queue<node> q;

node nd;
bool flag=0;

void bfs()
{
    flag=0;
    while(!q.empty())q.pop();
    nd.x=0;
    nd.y=0;
    nd.num=0;
    if(mp[0][0]==-1)
    {
        flag=1;
        return ;
    }
    else if(mp[0][0]==0)return ;
    q.push(nd);
    vis[nd.x][nd.y]=1;
    while(!q.empty())
    {
        nd=q.front();
        q.pop();
        if(mp[nd.x][nd.y]==-1)
        {
            flag=1;
            break;
        }
        for(int i=0; i<4; i++)
        {
            int x=nd.x+mov1[i];
            int y=nd.y+mov2[i];
            if(x<0||y<0||vis[x][y]==1)continue;
            int z=nd.num+1;
            if(mp[x][y]==-1||mp[x][y]>z)
            {
                q.push(node(x,y,z));
                vis[x][y]=1;
            }
        }
    }
    return ;
}

int main()
{
    //freopen("in.in","r",stdin);
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(mp,-1,sizeof(mp));
        memset(vis,0,sizeof(vis));
        for(int i=1; i<=n; i++)
        {
            int x, y, z;
            scanf("%d%d%d",&x,&y,&z);
            if(mp[x][y]==-1||mp[x][y]>z)
                mp[x][y]=z;
            for(int i=0; i<4; i++)
                if(x+mov1[i]>=0&&y+mov2[i]>=0)//要判断是否越界,起初就是在这里跪到爽
                    if(mp[x+mov1[i]][y+mov2[i]]==-1||mp[x+mov1[i]][y+mov2[i]]>z)
                        mp[x+mov1[i]][y+mov2[i]]=z;
        }
        /*for(int j=5;j>=0;j--)
        {
            for(int i=0;i<=5;i++)
                printf("%d ",mp[i][j]);
            printf("\n");
        }*/
        bfs();
        if(flag)
            printf("%d\n",nd.num);
        else
            printf("-1\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值