UVA 11853 Paintball(几何数学+DFS)
https://vjudge.net/problem/UVA-11853
根据题意描述,相当于在一个正方形中有若干个圆形障碍物,问是否能从左边界走到右边界。判断是否有解需要一点创造性的思维:不妨把正方形当做一个湖,所有的圆形都是垫脚石,假设我们可以从上边界“踩着”垫脚石成功走到下边界,说明左右边界是不连通的;否则就是连通的。想到了这里,便不难用dfs或bfs来判断是否有解了:每次都从和上边界相交的圆开始进行dfs,如果遇到某个圆和下边界也相交,那么无解。
这样解的存在性只需要一次DFS或者BFS判连通即可。如何求出最北的进/出位置呢?方法如下:从上边界开始遍历,沿途检查与边界相交的圆。这些圆和左边界的交点中最靠南边的一个就是所求的最北进入位置,和右边界的最南交点就是所求的最北离开位置。
1 #define _CRT_SECURE_NO_WARNINGS
2 #include<iostream>
3 #include<algorithm>
4 #include<string>
5 #include<sstream>
6 #include<set>
7 #include<vector>
8 #include<stack>
9 #include<map>
10 #include<queue>
11 #include<deque>
12 #include<cstdlib>
13 #include<cstdio>
14 #include<cstring>
15 #include<cmath>
16 #include<ctime>
17 #include<functional>
18 using namespace std;
19
20 #define N 1000+10
21 struct Circle
22 {
23 int x, y, r;
24 void read()
25 {
26 scanf("%d%d%d", &x, &y, &r);
27 }
28 }c[N];
29 double ans1, ans2;
30 int n, vis[N];
31
32 bool can(Circle a, Circle b)//判断两个圆是否相交或相切
33 {
34 int dx = a.x - b.x;
35 int dy = a.y - b.y;
36 return dx*dx + dy*dy - (a.r + b.r)*(a.r + b.r) <= 0;
37 }
38 bool dfs(int u)
39 {
40 vis[u] = 1;
41 if (c[u].y - c[u].r <= 0)return false;//圆和下边界有交点,说明不存在解,直接退出
42 if (c[u].x - c[u].r <= 0)ans1 = min(ans1, c[u].y - sqrt(c[u].r*c[u].r - c[u].x*c[u].x));//与左边界有交点,取纵坐标的较小者
43 if (1000 - c[u].x - c[u].r <= 0)ans2 = min(ans2, c[u].y - sqrt(c[u].r*c[u].r - (1000 - c[u].x)*(1000 - c[u].x)));//与右边界有交点,取纵坐标较小者
44 for (int i = 0; i < n; i++)
45 if (!vis[i])
46 {
47 if (can(c[u], c[i]))//路径可以继续扩展
48 if (!dfs(i))return false;
49 }
50 return true;
51 }
52 void solve()
53 {
54 ans1 = ans2 = 1000;
55 for (int i = 0; i < n; i++)
56 if (!vis[i] && c[i].y + c[i].r>=1000)//从与上边界有交点的圆出发
57 {
58 if (!dfs(i))//不存在解,如果存在解那么每次dfs后都会更新解
59 {
60 puts("IMPOSSIBLE");
61 return;
62 }
63 }
64 printf("0.00 %.2lf 1000.00 %.2lf\n", ans1, ans2);
65 }
66 int main()
67 {
68 //freopen("t.txt", "r", stdin);
69 while (~scanf("%d", &n))
70 {
71 memset(vis, 0, sizeof(vis));
72 for (int i = 0; i < n; i++)
73 c[i].read();//利用成员函数方便读入数据
74 solve();
75 }
76 return 0;
77 }
UVA 11853 Paintball(几何数学+DFS)的更多相关文章
- UVA - 11853 Paintball(dfs)
UVA - 11853 思路:dfs,从最上面超过上边界的圆开始搜索,看能不能搜到最下面超过下边界的圆. 代码: #include<bits/stdc++.h> using namespa ...
- UVA 11853 Paintball ——(dfs+圆交判定)
题意:给出一个1000*1000大小的矩阵,里面有若干圆,表示障碍物,现在要找出从左边到右边的一条通路,输出入口和出口的坐标,如果有多答案,输出y值最大的答案. 分析:从与上面相连的圆开始dfs,每次 ...
- UVA 11853 - Paintball 战场(dfs)
题意:有n个敌人,每个敌人有一个攻击范围,问你是否存在从西边到东边的路径,如果存在,输出入点和出点最靠北的坐标. 把每个敌人看出一个圆,从上往下跑dfs连通,如果到达底部,那么无解.要求出最靠北的坐标 ...
- Uva - 11853 - Paintball
先判断是否有解,从上到下dfs判断连通性,如果有从顶部到底部连通图,则无解.再判断最北的进出位置,从上边界开始遍历,沿途检查与边界相交的圆.这些圆的左边界的交点中最靠南边的一个就是所有的最北进入位置, ...
- UVA.297 Quadtrees (四分树 DFS)
UVA.297 Quadtrees (四分树 DFS) 题意分析 将一个正方形像素分成4个小的正方形,接着根据字符序列来判断是否继续分成小的正方形表示像素块.字符表示规则是: p表示这个像素块继续分解 ...
- B. Tell Your World(几何数学 + 思维)
B. Tell Your World time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- UVA 572 -- Oil Deposits(DFS求连通块+种子填充算法)
UVA 572 -- Oil Deposits(DFS求连通块) 图也有DFS和BFS遍历,由于DFS更好写,所以一般用DFS寻找连通块. 下述代码用一个二重循环来找到当前格子的相邻8个格子,也可用常 ...
- C. Polygon for the Angle 几何数学
C. Polygon for the Angle 几何数学 题意 给出一个度数 ,问可以实现的最小的n的n边形是多少 思路 由n边形的外角和是180度直接就可以算出最小的角是多少 如果给出的度数是其最 ...
- uva :10123 - No Tipping(dfs + 几何力矩 )
option=com_onlinejudge&Itemid=8&page=show_problem&category=109&problem=1064&mosm ...
随机推荐
- 用Matlab求解微分方程
用Matlab求解微分方程 解微分方程有两种解,一种是解析解,一种是数值解,这两种分别对应不同的解法 解析解 利用dsolve函数进行求解 syms x; s = dsolve('eq1,eq2,.. ...
- SpringBoot开发十三-检查登录状态
需求介绍-检查登录状态 防止用户知道我们的一些功能的链接,直接就进到了该页面,就像有些功能是管理员访问才能进的,就需要进行登录状态的判断. 我们知道这个功能点很多其他的功能点都需要使用,所以我们需要使 ...
- MongoDB实例重启失败探究(大事务Redo导致)
1.实例重启背景 收到监控组同学反馈,连接某一个MongoDB实例的应用耗时异常,并且出现了超时.查看数据库监控平台,发现此实例服务器的IO异常飙升,而查看副本集状态(rs.status()),主从是 ...
- 题解 P5038 [SCOI2012]奇怪的游戏
题解 题目 做这题之前,做了一道叫星际战争的题,很容易想到二分 \(+\) 网络流,那么二分啥呢? 我们先推一下式子,因为是对相邻格子加数,那么可以联想到黑白染色类问题. 设有黑色格子 \(B\) 个 ...
- 题解 [AHOI2017/HNOI2017]大佬
传送门 注意到题面里n很小,有\(n\leq100\) 考虑联系n的实际意义 n是你在大佬手中能活的天数 题面颇富深意 好了不闹了 n很小,对于\(40\%\)的数据,爆搜即可 考场上靠这个骗了40p ...
- 【java文件处理】java项目路径下的文件下载处理
1. controller类: package com.neo.controller; import javax.servlet.http.HttpServletResponse; import or ...
- 如何打一个RPM包
如何打一个RPM包 参考链接:RPM打包原理.示例.详解及备查 前言 本文只是一个RPM安装的例子,并没有对RPM做比较详尽的叙述,更为详尽的讲解,可以在上面的链接中找到. RPM是啥? RPM(Re ...
- FFmpeg 播放 RTSP/Webcam 流
本文将介绍 FFmpeg 如何播放 RTSP/Webcam/File 流.流程如下: RTSP/Webcam/File > FFmpeg open and decode to BGR/YUV & ...
- “类型思维”之Typescript,你掌握了吗?
(一)背景 JavaScript是一门动态弱类型语言 对变量的类型非常宽容 而且不会在这些变量和它们的调用者之间建立结构化的契约. 试想有这么几个场景: 1: 你调用一个别人写的函数,但是这个人没有写 ...
- VSCode Navigate Back/Forward
Navigate Back: In the menu bar Choose [Go] -> [Back] (Ctrl+Alt+-) Navigate Forward: In the menu b ...