zoukankan      html  css  js  c++  java
  • POJ 1735 Intervals

    POJ_1375

        这个题目可以先用解析几何的方法求出每个圆的两条切线并得到阴影部分,最后再将阴影部分合并即可。

        在合并阴影的时候,为了处理起来方便,可以先按左端点排序,这时可以从后往前枚举每个区间,然后从这个区间开始向前查找,如果前面某个区间和这个区间有交集,就删掉这个区间,并将前面那个区间的范围更新成两个区间的并集,这样做是O(n^2)的复杂度。

        更好的办法就是首先将第一个区间的左端点赋给x,右端点赋给y,然后依次向后扫描区间,如果当前区间的左端点比y大就输出记录的x、y,并将x、y更新成当前区间的左右端点的值,如果当前区间的左端点不比y大,那么就将y更新成当前区间的右端点及y两者的较大值,最后的时候再输出一下x、y,这样做是O(n) 的复杂度(只是指合并区间的这一环节的复杂度,前面对区间进行排序的复杂度是O(nlogn))。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<math.h>
    #define zero 1e-8
    #define MAXD 510
    int N, r[MAXD];
    double bx, by, cx[MAXD], cy[MAXD], cr[MAXD], lx[MAXD], rx[MAXD];
    int cmp(const void *_p, const void *_q)
    {
    int *p = (int *)_p;
    int *q = (int *)_q;
    return lx[*p] < lx[*q] ? -1 : 1;
    }
    double max(double x, double y)
    {
    return x > y ? x : y;
    }
    int dcmp(double x)
    {
    if(fabs(x) < zero)
    return 0;
    if(x < 0)
    return -1;
    return 1;
    }
    void init()
    {
    int i, j, k;
    scanf("%lf%lf", &bx, &by);
    for(i = 0; i < N; i ++)
    scanf("%lf%lf%lf", &cx[i], &cy[i], &cr[i]);
    }
    void solve()
    {
    int i, j;
    double k1, k2, a1, a2, a3, x, y;
    for(i = 0; i < N; i ++)
    {
    a1 = (cx[i] - bx) * (cx[i] - bx) - cr[i] * cr[i];
    a2 = 2 * (by - cy[i]) * (cx[i] - bx);
    a3 = (cy[i] - by) * (cy[i] - by) - cr[i] * cr[i];
    if(dcmp(a1) == 0)
    {
    k1 = (-a3) / a2;
    if(k1 < 0)
    lx[i] = bx, rx[i] = (-by) / k1 + bx;
    else
    lx[i] = (-by) / k1 + bx, rx[i] = bx;
    }
    else
    {
    k1 = (-a2 - sqrt(a2 * a2 - 4 * a1 * a3)) / (2 * a1);
    k2 = (-a2 + sqrt(a2 * a2 - 4 * a1 * a3)) / (2 * a1);
    lx[i] = (-by) / k1 + bx, rx[i] = (-by) / k2 + bx;
    }
    }
    for(i = 0; i < N; i ++)
    r[i] = i;
    qsort(r, N, sizeof(r[0]), cmp);
    x = lx[r[0]], y = rx[r[0]];
    for(i = 1; i < N; i ++)
    {
    if(dcmp(lx[r[i]] - y) > 0)
    {
    printf("%.2lf %.2lf\n", x, y);
    x = lx[r[i]], y = rx[r[i]];
    }
    else
    y = max(y, rx[r[i]]);
    }
    printf("%.2lf %.2lf\n", x, y);
    }
    int main()
    {
    for(;;)
    {
    scanf("%d", &N);
    if(!N)
    break;
    init();
    solve();
    printf("\n");
    }
    return 0;
    }


  • 相关阅读:
    C语言 百炼成钢1
    C语言 位运算
    GPS nmealib学习 问题
    c语言 GPS nmealib学习笔记
    ubuntu 12.04 以固定 IP 地址连接网络并配置DNS
    WGS84 2 GCJ-02
    【转】地球坐标系 (WGS-84) 到火星坐标系 (GCJ-02) 的转换算法 C#
    【转】地球坐标系 (WGS-84) 到火星坐标系 (GCJ-02) 的转换算法 C语言
    nmealib-0.5.3 问题 Build Error: undefined reference to `ceil'
    ArcGIS for WPF 访问外部资源
  • 原文地址:https://www.cnblogs.com/staginner/p/2354505.html
Copyright © 2011-2022 走看看