zoukankan      html  css  js  c++  java
  • 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
    ", 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 }
  • 相关阅读:
    u盘重装ubuntu16.04过程遇到的问题
    CTC安装及其错误解决办法:binding.cpp:92:49: error: cannot convert ‘THCudaTensor*’ to ‘const THFloatTensor*’ for argument ‘1’ to ‘int64_t THFloatTensor_size(const THFloatTensor*, int)’
    CTC安装错误之:binding.cpp:6:29: fatal error: torch/extension.h: No such file or directory
    机器学习入门(1)
    python学习笔记(1)
    python学习笔记(1)
    rpm命令的简介-(转自jb51.net )
    centos下安装visual studio code-(来自官网)
    ubuntu中安装visual studio code-(转载)
    git使用简单教程-(转自linux人)
  • 原文地址:https://www.cnblogs.com/YingZhixin/p/7518145.html
Copyright © 2011-2022 走看看