UVA 11853 Paintball ——(dfs+圆交判定)
Posted Storm_Spirit
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA 11853 Paintball ——(dfs+圆交判定)相关的知识,希望对你有一定的参考价值。
题意:给出一个1000*1000大小的矩阵,里面有若干圆,表示障碍物,现在要找出从左边到右边的一条通路,输出入口和出口的坐标,如果有多答案,输出y值最大的答案。
分析:从与上面相连的圆开始dfs,每次找与之相交的圆作为dfs的路径,如果能访问到下面,那么左边和右边肯定是不连通的;否则,连通。并且在dfs的时候更新y值最大的答案。
具体见代码:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <set> 5 #include <math.h> 6 using namespace std; 7 const int N = 1000 + 5; 8 const int inf = 2e9; 9 typedef long long ll; 10 typedef pair<int,int> pii; 11 12 int n; 13 int vis[N]; 14 struct circle 15 { 16 int x,y,r; 17 void read() 18 { 19 scanf("%d%d%d",&x,&y,&r); 20 } 21 }c[N]; 22 23 bool can(circle a,circle b) 24 { 25 double dx = a.x - b.x; 26 double dy = a.y - b.y; 27 double d = sqrt(dx*dx+dy*dy); 28 return d <= a.r + b.r; 29 } 30 31 double ansL = 0, ansR = 0; 32 void update(int u) 33 { 34 if(c[u].x <= c[u].r) 35 { 36 double t = sqrt(c[u].r*c[u].r - c[u].x*c[u].x); 37 double pos = c[u].y - t; 38 ansL = min(ansL, pos); 39 } 40 if(c[u].x + c[u].r >= 1000) 41 { 42 double tt = 1000.0 - c[u].x; 43 double t = sqrt(c[u].r*c[u].r - tt*tt); 44 double pos = c[u].y - t; 45 ansR = min(ansR, pos); 46 } 47 } 48 49 bool dfs(int u) 50 { 51 vis[u] = 1; 52 if(c[u].y <= c[u].r) return false; 53 update(u); 54 for(int i=1;i<=n;i++) 55 { 56 if(!vis[i] && can(c[u], c[i])) 57 { 58 if(!dfs(i)) return false; 59 } 60 } 61 return true; 62 } 63 64 void solve() 65 { 66 ansL = 1000, ansR = 1000; 67 memset(vis,0,sizeof(vis)); 68 for(int i=1;i<=n;i++) 69 { 70 if(!vis[i] && c[i].y + c[i].r >= 1000) 71 { 72 if(!dfs(i)) 73 { 74 puts("IMPOSSIBLE"); 75 return ; 76 } 77 } 78 } 79 printf("0.00 %.2f 1000.00 %.2f\n",ansL,ansR); 80 } 81 82 int main() 83 { 84 while(scanf("%d",&n) == 1) 85 { 86 for(int i=1;i<=n;i++) c[i].read(); 87 solve(); 88 } 89 return 0; 90 }
以上是关于UVA 11853 Paintball ——(dfs+圆交判定)的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ1709: [Usaco2007 Oct]Super Paintball超级弹珠
bzoj 1709: [Usaco2007 Oct]Super Paintball超级弹珠枚举