• P1849 [USACO12MAR]拖拉机Tractor bfs


    经过一天漫长的工作,农场主 John 完全忘记了他的拖拉机还在场地中央。他的奶牛们总喜欢和他搞些恶作剧,它们在场地的不同位置丢下 N(1 ≤ N ≤ 50,000)堆干草。这样 John 就必须先移走一些干草堆才能将拖拉机开走。

    拖拉机和干草堆都可以看作是二维平面上的点,它们的坐标都是整数,坐标范围在 1 到1000 之间。没有那堆干草的坐标和拖拉机的初始坐标一致。John 驾驶拖拉机只能沿着坐标轴的方向移动若干单位长度,比如说,他可以先朝北移动 2 个单位长度,再向东移动 3 个单位长度等等。拖拉机不能移动到干草堆所占据的点。

    请你帮助 John 计算一下,最少要移动多少堆干草才能将拖拉机开会坐标原点。

    输入输出格式

    输入格式:

    第一行,三个用空格隔开的整数 N、x、y,表示有N 堆干草和拖拉机的起始坐标。

    第 2行到第N+1 行,每行两个用空格隔开的整数 x、y,表示每堆干草的坐标。

    输出格式:

    一行一个整数,表示最少要移动多少堆干草 John 才能将拖拉机开会坐标原点。

    输入输出样例

    输入样例#1: 复制
    7 6 3 
    6 2 
    5 2 
    4 3 
    2 1 
    7 3 
    5 4 
    6 4 
    输出样例#1: 复制
    1 

    本身是一个比较简单的bfs 但是用之前的优先队列差点超时7000ms
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=1100;
    const int M=4e6+54;
    
    int dx[]={-1,0,1,0};
    int dy[]={0,-1,0,1};
    struct node
    {
        int x,y,d;
        bool operator<(const node& b)const
        {
            return d>b.d;
        }
    };
    int mp[N][N],n,sx,sy,vis[N][N];
    
    int bfs()
    {
        priority_queue<node>q;
        q.push(node{sx,sy,0});
        vis[sx][sy]=1;
        while(!q.empty())
        {
            node u=q.top();q.pop();
            if(u.x==0&&u.y==0)return u.d;
    
            rep(i,0,3)
            if(u.x+dx[i]>=0&&u.x+dx[i]<=1001&&u.y+dy[i]>=0&&u.y+dy[i]<=1001&&!vis[u.x+dx[i]][u.y+dy[i]])
            {
                if(mp[u.x+dx[i]][u.y+dy[i]])
                q.push(node{u.x+dx[i],u.y+dy[i],u.d+1});
                else
                q.push(node{u.x+dx[i],u.y+dy[i],u.d});
                vis[u.x+dx[i]][u.y+dy[i]]=1;
            }
        }
        return 0;
    }
    int main()
    {
        RIII(n,sx,sy);
        rep(i,1,n)
        {
            int a,b;RII(a,b);
            mp[a][b]=1;
        }
        cout<<bfs();
        return 0;
    }
    View Code

    然后用pair就不会??? 时间差为三倍2000ms
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=1100;
    const int M=4e6+54;
    int x,y,step;
    int dx[]={-1,0,1,0};
    int dy[]={0,-1,0,1};
    
    int mp[N][N],n,sx,sy,vis[N][N];
    priority_queue <pair<int,pair<int,int> > > q;
    int bfs()
    {
    
        q.push(make_pair(0,make_pair(-sx,-sy)));
        vis[sx][sy]=1;
        while(!q.empty())
        {
            x=-q.top().second.first;
            y=-q.top().second.second;
            step=-q.top().first;
            q.pop();
            if(x==0&&y==0)return step;
    
            for(int i=0;i<4;i++)
            {
                if (x+dx[i]>=0 && x+dx[i]<=1050
                && y+dy[i]>=0 && y+dy[i]<=1050
                && !vis[x+dx[i]][y+dy[i]])
                {
                    if (mp[x+dx[i]][y+dy[i]])
                        q.push(make_pair(-step-1,make_pair(-x-dx[i],-y-dy[i])));
                    else
                        q.push(make_pair(-step,make_pair(-x-dx[i],-y-dy[i])));
                    vis[x+dx[i]][y+dy[i]]=1;
                }
            }
        }
    }
    int main()
    {
        RIII(n,sx,sy);
        rep(i,1,n)
        {
            int a,b;RII(a,b);
            mp[a][b]=1;
        }
        cout<<bfs();
        return 0;
    }
    View Code
    改成双端队列  维护一下其单调性  900ms
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=1100;
    int dx[]={-1,0,1,0};
    int dy[]={0,-1,0,1};
    struct node
    {
        int x,y,d;
        bool operator<(const node& b)const
        {
            return d>b.d;
        }
    };
    int mp[N][N],n,sx,sy,vis[N][N];
    deque<node>q;
    int bfs()
    {node u;
        q.push_front(node{sx,sy,0});
        vis[sx][sy]=1;
        while(!q.empty())
        {
            u=q.front();q.pop_front();
            if(u.x==0&&u.y==0)return u.d;
    
            rep(i,0,3)
            if(u.x+dx[i]>=0&&u.x+dx[i]<=1001&&u.y+dy[i]>=0&&u.y+dy[i]<=1001&&!vis[u.x+dx[i]][u.y+dy[i]])
            {
                if(mp[u.x+dx[i]][u.y+dy[i]])
                q.push_back(node{u.x+dx[i],u.y+dy[i],u.d+1});
                else
                q.push_front(node{u.x+dx[i],u.y+dy[i],u.d});
                vis[u.x+dx[i]][u.y+dy[i]]=1;
            }
        }
        return 0;
    }
    int main()
    {
        RIII(n,sx,sy);
        rep(i,1,n)
        {
            int a,b;RII(a,b);
            mp[a][b]=1;
        }
        cout<<bfs();
        return 0;
    }
    View Code

    貌似自己重载的优先队列会比自带的优先队列慢很多?



  • 相关阅读:
    侠客博客v1.0 正式版版本发布
    酒店分销赚钱
    备份VPS 每周同步文件
    关于伪原创编辑的技巧
    在线考试系统,按计划一点一点的开发。
    WORDPRESS”丢失计划任务”
    钦和SEO服务DLL
    ORM之MySoft_Data测试成功。应该是非常好用的。
    发送了50左右篇博客文章
    writeFlashHTML,一个JS方法,主要用于Flash的输出。
  • 原文地址:https://www.cnblogs.com/bxd123/p/10959160.html
Copyright © 2020-2023  润新知