UVA
来源:互联网 发布:电视频道直播软件 编辑:程序博客网 时间:2024/06/16 05:26
题目链接
题意
如果大家是从lrj的书中例题看到本题,相信对题意不会太陌生,所以就不重复说了
解题思路
书中lrj也讲了思路,代码也可以下载,这篇博客就是说明一下为什么入口和出口的求法的正确性。
从图片中可以看到样例有解。建议大家先阅读了代码中求法及在什么条件下调用该函数。看了后发现是在dfs中调检查该圆是否与左边相交,如果相交说明从该圆与左边的下交点到(0,1000)都不能作为入口;如下图所示
图中与该条路径已经没有延伸,调用check_circle(),求得点left既为入口最靠北的点;ps:我对与题目中所说的严格大于敌人攻击范围的条件,但所求的确是等于的情况有点疑惑。
如上图是有延伸的情况,但是依然满足上面所说的最小交点(y值最小)便是满足题意的入口。求出口的原理与入口相同。
代码
// UVa11853 Paintball// Rujia Liu#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<algorithm>using namespace std;const int maxn = 1000 + 5;const double W = 1000.0;int n, vis[maxn];double x[maxn], y[maxn], r[maxn], left, right;bool ok;bool intersect(int c1, int c2){ return sqrt((x[c1]-x[c2])*(x[c1]-x[c2]) + (y[c1]-y[c2])*(y[c1]-y[c2])) < r[c1] + r[c2];}void check_circle(int u){ if(x[u] - r[u] < 0) left = min(left, y[u] - sqrt(r[u]*r[u] - x[u]*x[u])); if(x[u] + r[u] > W) right = min(right, y[u] - sqrt(r[u]*r[u] - (W-x[u])*(W-x[u])));}// 能达到底部则返回truebool dfs(int u){ if(vis[u]) return false; vis[u] = 1; if(y[u] - r[u] < 0) return true; for(int v = 0; v < n; v++) if(intersect(u, v) && dfs(v)) return true; check_circle(u); return false;}int main(){ while(scanf("%d", &n) == 1) { ok = true; left = right = W; memset(vis, 0, sizeof(vis)); for(int i = 0; i < n; i++) scanf("%lf%lf%lf", &x[i], &y[i], &r[i]); for(int i = 0; i < n; i++) if(y[i] + r[i] >= W && dfs(i)) { ok = false; // 从上往下dfs break; } if(ok) printf("0.00 %.2lf %.2lf %.2lf\n", left, W, right); else printf("IMPOSSIBLE\n"); } return 0;}
阅读全文
0 0
- uva
- UVA
- UVA
- UVA
- uva
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- 单片机串口通信电平不匹配的解决电路
- 滑块运动 — 上下
- STL
- kafka 0.10 client使用例子
- Windows下用anaconda装python,添加jupyter的kernel以及装包
- UVA
- DOM包裹wrap()方法
- 2017第二次多校联合 hdu6045Is Derek lying?
- 使用 Ruby on Rails 快速开发 Web 应用程序
- JSON数据解析
- 机器学习基础算法
- [解决办法]ubuntu登录界面一直进不去,因为修改profile--(ubuntu安装node.js)
- Mysql引擎Innodb和MyIASM
- WebUploader单击选择文件按钮无效