2541: [Ctsc2000]冰原探险

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 39  Solved: 25
[Submit][Status][Discuss]

Description

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

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

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

Input

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

Output

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

Sample Input

2
1 1
5 5
1 3 3 3
6 2 8

Sample Output

HINT

数据如下:JudgeOnline/upload/201604/2541.rar

Source

[Submit][Status][Discuss]

【题解】【BFS】

【算法简单,但乍一看没什么思路。就算是想到BFS也是很暴力的直接BFS】

【实际这道题,因为整个网格没有边界,所以不能直接暴力。由于每一次推小冰块只有在打到冰山才停止。我们可以预处理若冰块打到当前冰山的当前面,下一次可能再打到哪一冰山的哪一面。】

【so,我们把每一冰山的每一面作为一个点,由当前点向可能转移到的点连有向边,并把最开始的小冰块和深洞也作为一个点】

【预处理后,跑BFS最短路】

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
struct node{ll up,down,left,right;int num[5];
}ice[4010];
queue<int>que;
int a[200010],nxt[200010],p[200010],tot;
ll xi,yi,xt,yt;
int n,cnt,dis[200010];
bool vis[200010];
int tmp(node a,node b)
{if(a.down<b.down) return 1;if(a.down>b.down) return 0;if(a.left<b.left) return 1;return 0;
}
inline void add(int x,int y)
{tot++; a[tot]=y; nxt[tot]=p[x]; p[x]=tot;
}
inline int find_up(ll x,ll y,int opt)
{int ans=-1,low=-1;for(int i=1;i<=n;++i)if(i!=opt)if(ice[i].left<=x&&ice[i].right>=x&&ice[i].down>=y)if(low==-1||low>ice[i].down) low=ice[i].down,ans=ice[i].num[1];if(x==xt&&y<=yt&&(low>=yt||low==-1)) return cnt;return ans;
}
inline int find_down(ll x,ll y,int opt)
{int ans=-1,high=-1;for(int i=1;i<=n;++i)if(opt!=i)if(ice[i].left<=x&&ice[i].right>=x&&ice[i].up<=y)if(high==-1||high<ice[i].up) high=ice[i].up,ans=ice[i].num[2];if(x==xt&&y>=yt&&(high<=yt||high==-1)) return cnt;return ans;
}
inline int find_left(ll x,ll y,int opt)
{int ans=-1,lmax=-1;for(int i=1;i<=n;++i)if(opt!=i)if(ice[i].up>=y&&ice[i].down<=y&&ice[i].right<=x)if(lmax==-1||lmax<ice[i].right) lmax=ice[i].right,ans=ice[i].num[4];if(y==yt&&x>=xt&&(lmax<=xt||lmax==-1)) return cnt;return ans;
}
inline int find_right(ll x,ll y,int opt)
{int ans=-1,rmin=-1;for(int i=1;i<=n;++i)if(opt!=i)if(ice[i].up>=y&&ice[i].down<=y&&ice[i].left>=x)if(rmin==-1||rmin>ice[i].left) rmin=ice[i].left,ans=ice[i].num[3];if(y==yt&&x<=xt&&(rmin>=xt||rmin==-1)) return cnt;return ans;
}
inline void bfs()
{int inf;memset(dis,127/3,sizeof(dis));que.push(1); vis[1]=1; dis[1]=0; inf=dis[0];while(!que.empty()){int u=que.front(); que.pop();if(u==cnt) break;for(int i=p[u];i!=-1;i=nxt[i])if(dis[a[i]]>dis[u]+1){dis[a[i]]=dis[u]+1;if(!vis[a[i]]) que.push(a[i]),vis[a[i]]=1;}}if(dis[cnt]==inf) printf("0\n");else printf("%d\n",dis[cnt]);return;
}
int main()
{
//  freopen("ice.in","r",stdin);
//  freopen("ice.out","w",stdout);int i,j;memset(p,-1,sizeof(p));memset(nxt,-1,sizeof(nxt));scanf("%d",&n);scanf("%lld%lld%lld%lld\n",&xi,&yi,&xt,&yt);for(i=1;i<=n;++i) scanf("%lld%lld%lld%lld",&ice[i].left,&ice[i].down,&ice[i].right,&ice[i].up);sort(ice+1,ice+n+1,tmp);cnt=1;for(i=1;i<=n;++i)for(j=1;j<=4;++j)ice[i].num[j]=++cnt;int nm; cnt++;nm=find_up(xi,yi,0); if(nm!=-1) add(1,nm);nm=find_down(xi,yi,0); if(nm!=-1) add(1,nm);nm=find_left(xi,yi,0); if(nm!=-1) add(1,nm);nm=find_right(xi,yi,0); if(nm!=-1) add(1,nm); for(i=1;i<=n;++i){int l=ice[i].left,r=ice[i].right,u=ice[i].up,d=ice[i].down;nm=find_up(l-1,d,i); if(nm!=-1) add(ice[i].num[3],nm);nm=find_up(r+1,d,i); if(nm!=-1) add(ice[i].num[4],nm);nm=find_down(l-1,u,i); if(nm!=-1) add(ice[i].num[3],nm);nm=find_down(r+1,u,i); if(nm!=-1) add(ice[i].num[4],nm);nm=find_left(r,u+1,i); if(nm!=-1) add(ice[i].num[2],nm);nm=find_left(r,d-1,i); if(nm!=-1) add(ice[i].num[1],nm);nm=find_right(l,u+1,i); if(nm!=-1) add(ice[i].num[2],nm);nm=find_right(l,d-1,i); if(nm!=-1) add(ice[i].num[1],nm);}bfs();return 0;
}

[大模拟练码力...]

转载于:https://www.cnblogs.com/lris-searching/p/9403007.html

【bzoj 2541】 [Ctsc2000]冰原探险(BFS)相关推荐

  1. BZOJ 2246 [SDOI2011]迷宫探险 (记忆化搜索)

    题目大意:太长了,略 bzoj luogu 并没有想到三进制状压 题解: 3进制状压陷阱的状态,0表示这种陷阱的状态未知,1已知危险,2已知不危险 然后预处理出在当前状态下,每种陷阱有害的概率,设为$ ...

  2. BZOJ 2246 [SDOI2011]迷宫探险 ——动态规划

    概率DP 记忆化搜索即可,垃圾数据,就是过不掉最后一组 只好打表 #include <cstdio> #include <cstring> #include <iostr ...

  3. BZOJ.2246.[SDOI2011]迷宫探险(DP 记忆化搜索 概率)

    题目链接 求最大的存活概率,DP+记忆化. 用f[s][x][y][hp]表示在s状态,(x,y)点,血量为hp时的存活概率. s是个三进制数,记录每个陷阱无害/有害/未知. 转移时比较容易,主要是在 ...

  4. BZOJ刷题记录---提高组难度

    BZOJ刷题记录---提高组难度 总目录详见https://blog.csdn.net/mrcrack/article/details/90228694 序号 题号 算法 思想难度 实现难度 总难度 ...

  5. [BZOJ 1098] [POI2007] 办公楼biu 【链表优化BFS】

    题目链接:BZOJ - 1098 题目分析 只有两个点之间有边的时候它们才能在不同的楼内,那么就是说如果两个点之间没有边它们就一定在同一座楼内. 那么要求的就是求原图的补图的连通块. 然而原图的补图的 ...

  6. 搜索算法(三)--DFS/BFS求解宝岛探险问题(JAVA )

    宝岛探险问题 问题描述:某片海域有诸多岛屿,用0表示海洋,1-9表示陆地,现给定一个岛屿上的坐标点,求解所在岛屿的面积 思路:显然这是一个搜索算法,即只要从当前坐标点开始遍历,每遍历到一个点进行计数即 ...

  7. 宝岛探险(C语言 )(DFS+BFS)

    宝岛探险 某岛是由一个主岛和一些附属岛屿组成,小哼决定去某岛探险.下面这个10*10的二维矩阵就是某岛的航拍地图.图中数字表示海拔,0表示海洋,1~9表示陆地.小哼的飞机将会降落在(6,8)处,现在需 ...

  8. 【BZOJ 1415】 1415: [Noi2005]聪聪和可可 (bfs+记忆化搜索+期望)

    1415: [Noi2005]聪聪和可可 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1640  Solved: 962 Description ...

  9. bzoj 1632: [Usaco2007 Feb]Lilypad Pond【bfs】

    直接bfs,在过程中更新方案数即可 #include<iostream> #include<cstdio> #include<queue> using namesp ...

  10. 【BZOJ 1098】办公楼(补图连通块个数,Bfs)

    补图连通块个数这大概是一个套路吧,我之前没有见到过,想了好久都没有想出来QaQ 事实上这个做法本身就是一个朴素算法,但进行巧妙的实现,就可以分析出它的上界不会超过 $O(n + m)$. 接下来介绍一 ...

最新文章

  1. python代码实现堆排序
  2. CNN网络架构演进:从LeNet到DenseNet
  3. android学习笔记34——ClipDrawable资源
  4. linux下修改组的密码,Linux用户和组的操作(八) 修改用户密码 passwd
  5. Pytorch的网络结构可视化:Netron与TensorBoardX
  6. CodeForces - 1335E2 Three Blocks Palindrome (hard version)(思维)
  7. 分享一张前端知识点思维导图
  8. 【原创翻译】The Free Lunch Is Over
  9. 线性dp——cf988F
  10. Acrobat Pro DC 教程,如何将纸质文档转换为可搜索的 PDF 文件?
  11. python3中input输入浅谈_对Python3中的input函数详解
  12. 中华老黄历下载手机版免费_中华老黄历下载安装到手机-中华老黄历软件下载5.4.5 官方下载最新版-东坡下载...
  13. Python学习笔记(15)-Python常用模块总结
  14. 窃钩者诛,“窃脸”者___?
  15. 酷狗及一些播放软件收费歌曲下载方法
  16. 声纹识别开源框架python_GitHub - yeyupiaoling/VoiceprintRecognition-Tensorflow: 使用Tensorflow实现声纹识别,博客地址:...
  17. Failed to load local image resource /pages/pics/cloud://xxxxxxxxx.jpg
  18. Page not found (404) Request Method: GET Request URL: http://127.0.0.1:8000/ Using the URLconf defin
  19. IOS漏洞频出!世界上真的存在没有漏洞的手机吗?
  20. 现代人遇到鸿蒙碎片,原来我是盖世奶爸-第126章 虚空之门是鸿蒙鼎碎片?

热门文章

  1. Linux下如何编写和使用自定义的Shell函数和函数库
  2. 《Cocos2D-x权威指南》——3.1 节点类
  3. SQL Server 2008支持将数据导出为脚本
  4. c++11支持类数据成员的初始化
  5. memcached安装和使用
  6. bagging算法_Bagging与随机森林算法及其变种
  7. 计算机上相同的用户,php会话为不同计算机上的不同用户发出相同的session_id
  8. yaml和properties文件相互转换的网站
  9. 地面控制点的定义与作用_彩色透水混凝土路面在海绵城市建设中能起多大作用?...
  10. 学习单片机入门以后可以做什么?