题面

题目背景
传说中,南极有一片广阔的冰原,在冰原下藏有史前文明的遗址。整个冰原被横竖划分成了很多个大小相等的方格。在这个冰原上有N个大小不等的矩形冰山,这些巨大的冰山有着和南极一样古老的历史,每个矩形冰山至少占据一个方格,且其必定完整地占据方格。冰山和冰山之间不会重叠,也不会有边或点相连。以下两种情况均是不可能出现的:

题目描述
ACM探险队在经过多年准备之后决定在这个冰原上寻找遗址。根据他们掌握的资料,在这个冰原上一个大小为一格的深洞中,藏有一个由史前人类制作的开关。而唯一可以打开这个开关的是一个占据接近一格的可移动的小冰块。显然,在南极是不可能有这样小的独立冰块的,所以这块冰块也一定是史前文明的产物。他们在想办法把这个冰块推到洞里去,这样就可以打开一条通往冰原底部的通道,发掘史前文明的秘密。冰块的起始位置与深洞的位置均不和任何冰山相邻。这个冰原上的冰面和冰山都是完全光滑的,轻轻的推动冰块就可以使这个冰块向前滑行,直到撞到一座冰山就在它的边上停下来。冰块可以穿过冰面上所有没有冰山的区域,也可以从两座冰山之间穿过(见下图)。冰块只能沿网格方向推动。

请你帮助他们以最少的推动次数将冰块推入深洞中。

输入格式:
输入文件第一行为冰山的个数N (1<=N<=4000),第二行为冰块开始所在的方格坐标X1,Y1,第三行为深洞所在的方格坐标X2,Y2,以下N行每行有四个数,分别是每个冰山所占的格子左上角和右下角坐标Xi1,Yi1,Xi2,Yi2

输出格式:
输出文件仅包含一个整数,为最少推动冰块的次数。如果无法将冰块推入深洞中,则输出0。

说明
1<=N<=4000

思路

关键:
1.map key取2个值更方便
2.各种判断条件细节推导

主要思路就是要模拟出冰块再地图中直接移动到停下的点的状态来进行bfs
当前位置(x,y) 目标位置(ex,ey)
上 x1<=x<=x2 && max {y2} -> (x,y2+1)
下 x1<=x<=x2 && min {y1} -> (x,y1-1)
左 y1<=y<=y2 && max {x2} -> (x2+1,y)
右 y1<=y<=y2 && min {x1} -> (x1-1,y)
+ && 冰山的位置要与去的方向一致
1.冰山要在方向的那一边,与方向一致
2.下个点不能在原地
3.map对坐标判重
4.找不到时数值为inf,不能向后走
但不影响判断答案,因为inf时一定满足逻辑式
5.可以画图,写出来判断式后套bfs框架即可
6.每次向后走时直接枚举每一个冰山

代码

#include <cstdio>
#include <iostream>
#include <map>
#define re register
#define int long long
using namespace std;

const int inf = 1e9;
const int maxq = 2000005;
int n,bx,by,ex,ey,ans;
struct f {
    int x,y;
    bool operator < (const f &r) const{
        if(x == r.x) return y < r.y;
        return x < r.x;
    }
};
map<f,int> mp;
struct node {
    int x,y,step;
}q[maxq];
int head,tail;
struct point {
    int x1,y1,x2,y2;
}p[5005];
inline void Bfs()
{
    head = 0, tail = 1;
    q[1].x = bx, q[1].y = by, q[1].step = 0;
    mp[(f){bx,by}] = 1;
    while(head < tail)
    {
        head++; if(head >= maxq) head = 1;
        int x = q[head].x, y = q[head].y, step = q[head].step;
//      cout << x <<" " << y << " " << step << endl;
        //上
        int y2 = -inf;
        for(re int i = 1; i <= n; i++)
            if(p[i].x1 <= x && x <= p[i].x2 && p[i].y2 > y2 && p[i].y2 < y)
                y2 = p[i].y2;
        if(x == ex && ey > y2 && ey < y) {
            ans = step + 1;
            return;
        }
        if(y2 != -inf && mp[(f){x,y2+1}] == 0) {
            tail++; if(tail >= maxq) tail = 1;
            q[tail].x = x, q[tail].y = y2 + 1, q[tail].step = step + 1;
            mp[(f){x,y2+1}] = 1;
        }
        //下
        int y1 = inf;
        for(re int i = 1; i <= n; i++)
            if(p[i].x1 <= x && x <= p[i].x2 && p[i].y1 < y1 && p[i].y1 > y)
                y1 = p[i].y1;
        if(x == ex && ey < y1 && ey > y) {
            ans = step + 1;
            return;
        }
        if(y1 != inf && mp[(f){x,y1-1}] == 0) {
            tail++; if(tail >= maxq) tail = 1;
            q[tail].x = x, q[tail].y = y1 - 1, q[tail].step = step + 1;
            mp[(f){x,y1-1}] = 1;
        }
        //左
        int x2 = -inf;
        for(re int i = 1; i <= n; i++)
            if(p[i].y1 <= y && y <= p[i].y2 && p[i].x2 > x2 && p[i].x2 < x)
                x2 = p[i].x2;
        if(y == ey && ex > x2 && ex < x) {
            ans = step + 1;
            return;
        }
        if(x2 != -inf && mp[(f){x2+1,y}] == 0) {
            tail++; if(tail >= maxq) tail = 1;
            q[tail].x = x2 + 1, q[tail].y = y, q[tail].step = step + 1;
            mp[(f){x2+1,y}] = 1;
        }
        //右
        int x1 = inf;
        for(re int i = 1; i <= n; i++)
            if(p[i].y1 <= y && y <= p[i].y2 && p[i].x1 < x1 && p[i].x1 > x)
                x1 = p[i].x1;
        if(y == ey && ex < x1 && ex > x) {
            ans = step + 1;
            return;
        }
        if(x1 != inf && mp[(f){x1-1,y}] == 0) {
            tail++; if(tail >= maxq) tail = 1;
            q[tail].x = x1 - 1, q[tail].y = y, q[tail].step = step + 1;
            mp[(f){x1-1,y}] = 1;
        }
    }
}
signed main()
{
    scanf("%lld", &n);
    scanf("%lld%lld%lld%lld", &bx, &by, &ex, &ey);
    for(int i = 1; i <= n; i++)
        scanf("%lld%lld%lld%lld", &p[i].x1, &p[i].y1, &p[i].x2, &p[i].y2);
    Bfs();
    printf("%lld\n", ans);
    return 0;
}

[题目] Luogu P3716 [CTSC2000]冰原探险的更多相关文章

  1. [Ctsc2000]冰原探险

    Description 传说中,南极有一片广阔的冰原,在冰原下藏有史前文明的遗址.整个冰原被横竖划分成了很多个大小相等的方格.在这个冰原上有N个大小不等的矩形冰山,这些巨大的冰山有着和南极一样古老的历 ...

  2. BZOJ 2541: [Ctsc2000]冰原探险

    Descrption 有一些矩形障碍,碰到障碍会停下,求从一个点到另一个点的最少移动步数. Sol BFS. 因为题目的特殊性质,两个矩形没有任何相邻,起始点和终点和矩形没有相邻. 所以从一个点的移动 ...

  3. 【[CTSC2000]冰原探险】

    noip前练一下码力还是非常有前途的 这道题本来就是想写个大暴力弃疗的,所以直接强上暴力浑身舒爽 结果发现要不是判重的时候脑残了,就能\(A\)了 没什么好说的呀,就是每一次都暴力\(O(n)\)往上 ...

  4. [题目] Luogu P3707 [SDOI2017]相关分析

    参考资料:[Luogu 3707] SDOI2017 相关分析 P3707 [SDOI2017]相关分析 TFRAC FRAC DFRAC \(\tfrac{\sum}{1}\) \(\frac{\s ...

  5. [题目] Luogu P1312 Mayan游戏

    题面 题目描述 $ Mayan puzzle $是最近流行起来的一个游戏.游戏界面是一个 \(7行 \times 5列\)的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放 ...

  6. 【Luogu】P2489迷宫探险(概率DP)

    题目链接 设f[i][j][k][l]是当前在(i,j),对陷阱的了解状态为k(0表示了解该陷阱为无危险,1表示了解该陷阱有危险,2不了解),l表示当前血,走出迷宫的概率 dfsDP即可. 注意随时更 ...

  7. 【Luogu】P3356火星探险问题(费用流)

    题目链接 网络流一条边都不能多连?没道理呀? 不过单看这题的确是个sb题…… #include<cstdio> #include<algorithm> #include< ...

  8. 【BZOJ 2541】【Vijos 1366】【CTSC 2000】冰原探险

    http://www.lydsy.com/JudgeOnline/problem.php?id=2541 https://vijos.org/p/1366 loli秘制大爆搜_(:з」∠)_坑了好久啊 ...

  9. [题目] Luogu P5038 [SCOI2012]奇怪的游戏

    学习资料 -----1----- -----2----- P5038 [SCOI2012]奇怪的游戏 一道甚神但没用到高深模型的题 思路 没思路,看题解吧 代码 #include <iostre ...

随机推荐

  1. TRIZ解决问题方法

    个人觉的成功是有规律的,那些成功的人士,都有一套处理事情的秘籍.只要我们的思维方式把那些秘籍融会贯通,并快速执行,我们有一天也会成功的. TRIZ解决问题的5点方法. 1.确定最终目标. 2.列出阻碍 ...

  2. LDA算法学习(Matlab实现)

    LDA算法 对于两类问题的LDA(Matlab实现) function [ W] = FisherLDA(w1,w2) %W最大特征值对应的特征向量 %w1 第一类样本 %w2 第二类样本 %第一步: ...

  3. JavaScript 日期多加一天 方法

    今天查看项目发现有出bug,由于未了符合sql语句的要求,前台网页显示的时候传到后台的时候要+1天, 网上查看了别人写的,发现多多少少有点漏洞,经过我自己总结,写出了达到了我要求的 var str = ...

  4. [日常] Go语言圣经-Deferred函数

    1.只需要在调用普通函数或方法前加上关键字defer,就完成了defer所需要的语法.当defer语句被执行时,跟在defer后面的函数会被延迟执行.直到包含该defer语句的函数执行完毕时,defe ...

  5. [日常] Go语言圣经--包和文件-导入包习题

    1.每个包都有一个全局唯一的导入路径 2.按照惯例,一个包的名字和包的导入路径的最后一个字段相同 练习 2.2: 写一个通用的单位转换程序,用类似cf程序的方式从命令行读取参数,如果缺省的话则是从标准 ...

  6. Quoit Design(hdu1007)最近点对问题。模版哦!

    Quoit Design Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...

  7. Java 初级面试题及答案

    1.Java中的重载与重写有什么区别 重载(Overload)是让类以统一的方式处理不同类型数据的一种手段,实质表现就是多个具有不同的参数个数或者类型的同名函数(返回值类型可随意,不能以返回类型作为重 ...

  8. 获取本机的ip地址(排除虚拟机,蓝牙等ip)

    项目中遇到了要获取本地ip的需求,网上查找资料遇到很多坑,很多Java获取本机ip地址的方法要么是根本获取不到,要么是获取的有问题. 网上常见的方法如下 InetAddress.getLocalHos ...

  9. POJ2387(KB4-A)

    Til the Cows Come Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 54716   Accepted ...

  10. php递归获取无限分类菜单

    从数据库获取所有菜单信息,需要根据id,pid字段获取主菜单及其子菜单,以及子菜单下的子菜单,可以通过函数递归来实现. <?php class Menu { public $menu = arr ...