洛谷P1783 海滩防御 分析+题解代码
来源:互联网 发布:数据库管理系统厂商 编辑:程序博客网 时间:2024/04/19 18:01
洛谷P1783 海滩防御 分析+题解代码
题目描述:
WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭。于是,WLP动用了他那丰满且充实的大脑(或许更偏向前者),想出了一个好主意,他把海滩分成垂直于海岸线的若干列,在其中的几列上放置几个信号塔,试图来监视整个海滩。然而,WLP是一个非常心急的人,他把信号塔建好后才发现还需给信号塔供能,它们才能投入使用(这不是废话么),它们都有一个工作半径,一个圆形区域里的所有敌人都逃不过它们的监视,不过,WLP发现,敌人们非常狡猾,除非他将道路完全封死,否则WLP的敌人可以走过一条任意弯曲的路(不一定走整点,但是不会出第0列和第N列构成的边界)来偷他的东西。
于是,WLP就思考了:到底需要给每个信号塔多大的工作半径,才能将从海滩到内地的路径完全封死呢?他再次动用了他那丰满且充实的大脑,想了一堂数学课,终于,还是没想出来。于是,他向LZZ神犇求助(额……C_SUNSHINE的身份是不是暴露了)。
终于,在WLP:“%^!@#!(^!#@$^&(此处省略无数卖萌场景)”的哀求下,LZZ神犇写了一个程序,在1s内就解决了问题。但是,邪恶的LZZ神犇决定要将这个难题共享给无数无辜的OIer,所以,现在轮到你了。
输入格式:
第一行两个整数N和M:表示海滩被WLP分成的列数0-N和信号塔个数。
第2-M+1行:每行两个数Xi,Yi表示1-M号信号塔所在的列数和离开海滩的距离。
输出格式:
一行一个实数,表示最小的工作半径,保留两位小数。
样例输入1:
5 5
1 5
3 5
5 5
4 30
2 15
样例输出1:
1.00
样例输入2:
100 2
30 50
90 100
样例输出2:
39.05
说明:
对于10%的数据:1≤M≤10,1≤Yi≤100;
对于30%的数据:1≤M≤50,1≤Yi≤1,000;
对于80%的数据:1≤M≤500,1≤Yi≤1,000;
对于100%的数据:1≤M≤800,1≤N≤1000,1≤Xi≤N,1≤Yi≤100,000.
【样例解释】
注意,封锁海滩是指,敌人的深入程度是有限制的,若敌人绕过了所有的信号塔,并且可以长驱直入,那么就说明道路没有完全封锁。
算法分析:
这道题一开始想到了二分
但普通的二分过不了
需要加上一些奇奇怪怪的剪枝
即便这样复杂度依旧很高,只是刚好可以卡过题目
所以我们换个思路
这里我们可以借鉴一下最小生成树的思想
即将整个图的所有边存于一个数组中(此步骤可以在输入防御塔坐标时完成)
此时图中只有节点而无边
将所有边按长度从小到大排序
然后依次加入这些边
每加入一条边就dfs遍历整个图
若此时图中某个联通块可以遍历到左右边界
此时的边权即为所求答案
还有几点需要注意的是
- 由于所求的是最小半径,所以计算边权的时候要将两点间距离除以二作为边权
- 海滩的列数编号为0~n,而0与n不能通行,所以左右边界为1与n-1
接下来献上蒟蒻的代码
#include<iostream>#include<algorithm>#include<vector>#include<cstdio>#include<cmath>#include<cstring>using namespace std;const int maxn=1000010;typedef double dd;int n,m;struct node{ dd x; dd y;}pt[maxn];struct edge{ int u; int v; dd dis;}E[1000010];bool vis[maxn];bool lft,rht;//判断是否联通左右边界 vector<int> map[maxn]; dd dist(node a,node b){ dd tx=fabs(a.x-b.x); dd ty=fabs(a.y-b.y); tx*=tx; ty*=ty; return sqrt(tx+ty);}void dfs(int u,dd dis){ vis[u]=true; //若到达左/右边界则记录 if(pt[u].y+dis>=n-1) rht=true; if(pt[u].y-dis<=1) lft=true; for(int j=0;j<map[u].size();j++) { int v=map[u][j]; if(vis[v]==false) dfs(v,dis); }}bool cmp(edge a,edge b){ return a.dis<b.dis;}int main(){ cin>>n>>m; for(int i=1;i<=m;i++) { cin>>pt[i].y>>pt[i].x; for(int j=1;j<i;j++)//在这里建边 { E[++cont].u=i; E[cont].v=j; E[cont].dis=dist(pt[i],pt[j])/2.0; //记得边权=两点距离/2.0 } } sort(E+1,E+1+cont,cmp); for(int i=1;i<=cont;i++)//从小到大加入每条边 { map[E[i].u].push_back(E[i].v); map[E[i].v].push_back(E[i].u); for(int j=1;j<=m;j++) { if(vis[j]==false) dfs(j,E[i].dis); if(lft&&rht)//若联通则直接输出并退出程序 { printf("%.2lf",E[i].dis); return 0; } else lft=rht=false; //注意判断封锁要在同一联通快内,所以每次都要重置 } memset(vis,false,sizeof(vis)); } return 0;}
其实我们在边的加入时还可以有优化
但是由于本蒟蒻比较懒
所以不想在优化了。。。。。。
- 洛谷P1783 海滩防御 分析+题解代码
- 洛谷 P1783 海滩防御
- 洛谷 1783 海滩防御
- 洛谷-1783 海滩防御
- 导弹防御塔(题解+代码)
- 关于海滩争霸Crab代码的理解
- 洛谷P1854 花店橱窗布置 分析+题解代码
- 洛谷P2832 行路难 分析+题解代码【玄学最短路】
- ios代码0727分析题解析
- NOI2001 食物链 题目分析&题解&代码
- 【BZOJ】【P3156】【防御准备】【题解】【斜率优化】
- 导弹防御塔(missble)题解
- 洛谷 P2194 HXY烧情侣【Tarjan缩点】 分析+题解代码
- 金海滩
- 海滩生活
- 海滩烧烤
- 这十二行代码是如何让浏览器爆炸的? -DoS攻击分析及防御
- js中的“十二行诗” ----12行JS代码的DoS攻击分析及其防御
- LoRa模块在无线抄表上的应用
- Tensorflow 同时载入多个模型
- 触发器
- JRE和JDK的概述
- 生成对抗网络GANs
- 洛谷P1783 海滩防御 分析+题解代码
- spark排错与优化
- 微信小程序(1 初识)
- 页面刷新vuex数据消失问题解决方案
- Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2018-04-30 of type java.tim
- SQL语法
- Mybatis 属性 无法 赋值
- springmvc上下文与springcontext上下文的关系
- 当袁立的天真遭遇浙江卫视内定黑幕,方知演技不在戏内而在戏外!