哎呀,做了1天的bfs,居然最后以后6个测试点tle告终(其余ac,56分)

P2895 [USACO08FEB] Meteor Shower S

gztony @ 2021-01-15 15:55:54

有哪位大神帮我看一下哪里需要优化,本咸鱼已经努力优化一次了!(使用了布尔型防重复走路数组)

#include<bits/stdc++.h>
using namespace std;
struct node{
    int x,y,t;
};
queue<node> walk;
int farm[305][305],meteor[50000][3],m;
const int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
bool vis[305][305];
void bfs(){
    int i,j,x,y,t,tx,ty;
    node tmp,cur;
    tmp.x=0;
    tmp.y=0;
    tmp.t=0;
    walk.push(tmp);
    while(!walk.empty()){
        cur=walk.front();
        x=cur.x;
        y=cur.y;
        t=cur.t;
        vis[x][y]=true;
        //cout<<x<<" "<<y<<" "<<t<<endl;
        if(farm[x][y]==0){
            cout<<t;
            return;
        }
        for(i=0;i<m;i++){
            if(t==meteor[i][2]){
                tx=meteor[i][0];
                ty=meteor[i][1];
                farm[tx][ty]=1;
                //cout<<tx<<" "<<ty<<endl;
                for(j=0;j<4;j++){
                    //cout<<" "<<tx+dx[j]<<" "<<ty+dy[j]<<endl;
                    if(tx+dx[j]>=0&&ty+dy[j]>=0)
                        farm[tx+dx[j]][ty+dy[j]]=1;
                }
            }
        }
        /*for(i=0;i<4;i++){
            for(int j=0;j<4;j++){
                cout<<farm[i][j]<<"\t";
            }
            cout<<endl;
        }*/
        if(farm[x][y]==1){
            /*cout<<-1;
            return;*/
            //cout<<"boom"<<endl;
            walk.pop();
            continue; 
        }
        for(i=0;i<4;i++){
            tx=x+dx[i];
            ty=y+dy[i];
            if(tx>=0&&ty>=0){
                if(farm[tx][ty]!=1&&!vis[tx][ty]){
                    tmp.x=tx;
                    tmp.y=ty;
                    tmp.t=t+1;
                    walk.push(tmp);
                }
            }
        }
        //t++;
        walk.pop();
    }
    cout<<-1;
}
int main(){
    int i,j,x,y;
    cin>>m;
    for(i=0;i<m;i++){
        cin>>meteor[i][0]>>meteor[i][1]>>meteor[i][2];
        x=meteor[i][0];
        y=meteor[i][1];
        farm[x][y]=-1;
        for(j=0;j<4;j++){
            //cout<<x+dx[j]<<" "<<y+dy[j]<<endl;
            if(x+dx[j]>=0&&y+dy[j]>=0)
                farm[x+dx[j]][y+dy[j]]=-1;
        }
    }
    bfs();
    return 0;
}

另外加注释的地方是用来调试的,供大家使用(微笑)(明明是懒得删)


by q779 @ 2021-01-15 16:13:10

for(i=0;i<m;i++){
            if(t==meteor[i][2]){
                tx=meteor[i][0];
                ty=meteor[i][1];
                farm[tx][ty]=1;
                //cout<<tx<<" "<<ty<<endl;
                for(j=0;j<4;j++){
                    //cout<<" "<<tx+dx[j]<<" "<<ty+dy[j]<<endl;
                    if(tx+dx[j]>=0&&ty+dy[j]>=0)
                        farm[tx+dx[j]][ty+dy[j]]=1;
            }
            }
  }

我觉得这一段没必要,也许可以和下一个循环合并(多加个判断)


by gztony @ 2021-01-15 16:19:36

@q779 谢谢大佬,不过能具体说明一下吗?这段是陨石轰炸农场的部分。请问您的意思是直接判定主角是不是站在一个正在或已经被轰炸过的格子吗?


by q779 @ 2021-01-15 16:25:08

@gztony 向四个方向搜的时候判断当前时间有没有被炸过,没有就可以继续搜


by gztony @ 2021-01-15 16:40:52

@q779 请问您的意思是,如果有一颗流星未轰炸,那么终止之后的轰炸?也许为此要按照流星的轰炸时间给流星排序。


by q779 @ 2021-01-15 16:55:49

@gztony 每一颗流星都有坠落时间,如果到达一个流星会炸到的格子时,流星还没有砸下来,那就可以走,但不能在此地停留(即输出步数)

如果到了一个格子永不会被炸,就输出时间

如果搜完了都没输出时间则说明不可能

你可以用数组标记流星会在t时刻炸到某位置,这样判断时只要看这个t是否大于当前时间


by gztony @ 2021-01-15 17:12:46

@q779 好的,谢谢大佬


|