【[CTSC2000]冰原探险】

noip前练一下码力还是非常有前途的

这道题本来就是想写个大暴力弃疗的,所以直接强上暴力浑身舒爽

结果发现要不是判重的时候脑残了,就能\(A\)

没什么好说的呀,就是每一次都暴力\(O(n)\)往上下左右扩展状态,之后放到队列里,\(map\)判重就好了

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<map>
#include<cstring>
#define mp std::make_pair
#define re register
#define maxn 4005
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
inline int read()
{
    char c=getchar();
    int x=0,r=1;
    while(c<'0'||c>'9') {if(c=='-') r=-1;c=getchar();}
    while(c>='0'&&c<='9')
        x=(x<<3)+(x<<1)+c-48,c=getchar();
    return x*r;
}
struct node
{
    int x,y,step;
};
std::map<std::pair<int,int> ,bool > vis;
inline void GG()
{
    puts("0");
    exit(0);
}
inline void kill(int a)
{
    printf("%d\n",a);
    exit(0);
}
int ix[maxn],iy[maxn],Ix[maxn],Iy[maxn];
int n,sx,sy,dx,dy;
inline void BFS()
{
    std::queue<node> q;
    q.push((node){sx,sy,0});
    vis[mp(sx,sy)]=1;
    while(!q.empty())
    {
        node mid=q.front();
        q.pop();
        int xx=mid.x,yy=mid.y;
        
        int pre=-99999999;
        for(re int i=1;i<=n;i++)
            if(yy>=iy[i]&&yy<=Iy[i]&&Ix[i]<=xx) pre=max(pre,Ix[i]);
        if(pre!=-99999999) 
        {
            if(pre!=xx&&!vis[mp(pre+1,yy)]) 
            {
                vis[mp(pre+1,yy)]=1,q.push((node){pre+1,yy,mid.step+1});
                if(dy==yy&&dx<xx&&xx>=pre+1) kill(mid.step+1);
            }
        }
        else if(dy==yy&&dx<xx) kill(mid.step+1);
        
        pre=999999999;
        for(re int i=1;i<=n;i++)
            if(yy>=iy[i]&&yy<=Iy[i]&&ix[i]>=xx) pre=min(pre,ix[i]);
        if(pre!=999999999)
        {
            if(pre!=xx&&!vis[mp(pre-1,yy)]) 
            {
                vis[mp(pre-1,yy)]=1,q.push((node){pre-1,yy,mid.step+1});
                if(dy==yy&&dx>xx&&xx<=pre-1) kill(mid.step+1);
            }
        }
        else if(dy==yy&&dx>xx) kill(mid.step+1);
        
        pre=-99999999;
        for(re int i=1;i<=n;i++)
            if(xx>=ix[i]&&xx<=Ix[i]&&Iy[i]<=yy) pre=max(pre,Iy[i]);
        if(pre!=-99999999) 
        {
            if(pre!=yy&&!vis[mp(xx,pre+1)]) 
            {
                vis[mp(xx,pre+1)]=1,q.push((node){xx,pre+1,mid.step+1});
                if(dx==xx&&dy<yy&&dy>=pre+1) kill(mid.step+1);
            }
        }
        else if(dx==xx&&dy<yy) kill(mid.step+1);
        
        pre=99999999;
        for(re int i=1;i<=n;i++)
            if(xx>=ix[i]&&xx<=Ix[i]&&iy[i]>=yy) pre=min(pre,iy[i]);
        if(pre!=99999999)   
        {
            if(pre!=yy&&!vis[mp(xx,pre-1)]) 
            {
                vis[mp(xx,pre-1)]=1,q.push((node){xx,pre-1,mid.step+1});
                if(dx==xx&&dy>yy&&dy<=pre-1) kill(mid.step+1);;
            }
        }
        else if(dx==xx&&dy>yy) kill(mid.step+1);
    }
    GG();
}
int main()
{
    n=read();
    sx=read(),sy=read(),dx=read(),dy=read();
    for(re int i=1;i<=n;i++) ix[i]=read(),iy[i]=read(),Ix[i]=read(),Iy[i]=read();
    BFS();
    return 0;
}

转载于:https://www.cnblogs.com/asuldb/p/10207898.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值