码迷,mamicode.com
首页 > 其他好文 > 详细

P1849 [USACO12MAR]拖拉机Tractor bfs

时间:2019-06-01 12:40:38      阅读:89      评论:0      收藏:0      [点我收藏+]

标签:一个   range   表示   输入格式   src   reg   space   inpu   empty   

经过一天漫长的工作,农场主 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

 

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

 



P1849 [USACO12MAR]拖拉机Tractor bfs

标签:一个   range   表示   输入格式   src   reg   space   inpu   empty   

原文地址:https://www.cnblogs.com/bxd123/p/10959160.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!