zoukankan      html  css  js  c++  java
  • COJ1107 UVA12296 Pieces and Discs 2011湖南省赛H题

    把每个交点映射为单独的id,map去重。对每个点建立相邻点的链表。枚举点,用相邻点链表找最左点,迭代绕出凸包,枚举圆判凸包与圆相交。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<math.h>
      5 #include<vector>
      6 #include<algorithm>
      7 #include<iostream>
      8 #include<map>
      9 using namespace std;
     10 const int maxn = 41;
     11 const int maxm = maxn * maxn;
     12 const double eps = 1e-8;
     13 const double pi = acos(-1.0);
     14 int dcmp(double x)
     15 {
     16     if(x < -eps) return -1;
     17     return x > eps;
     18 }
     19 struct Point
     20 {
     21     double x, y, r;
     22     bool operator <(const Point &b)const
     23     {
     24         if(dcmp(x - b.x) == 0)
     25             return y < b.y;
     26         return x < b.x;
     27     }
     28 };
     29 typedef struct
     30 {
     31     Point s, e;
     32     double ang, d;
     33 } Line;
     34 
     35 inline double det(double x1, double y1, double x2, double y2)
     36 {
     37     return x1 * y2 - x2 * y1;
     38 }
     39 double cross(Point a, Point b, Point c)
     40 {
     41     return det(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
     42 }
     43 Point MakePoint(double xx, double yy)
     44 {
     45     Point res;
     46     res.x = xx, res.y = yy;
     47     return res;
     48 }
     49 
     50 
     51 int n, m, L, W, pnum;
     52 vector<Point> ap;
     53 vector<int> lp[maxn], adjp[maxm];
     54 vector<Line> l;
     55 vector<double> ans[maxn];
     56 map<Point, int> M;
     57 Point c[maxn];
     58 bool visp[maxm];
     59 
     60 Line SetLine(Point a, Point b)
     61 {
     62     Line l;
     63     l.s = a;
     64     l.e = b;
     65     l.ang = atan2(b.y - a.y, b.x - a.x);
     66     if(dcmp(a.x - b.x)) l.d = (a.x * b.y - b.x * a.y) / fabs(a.x - b.x);
     67     else l.d = (a.x * b.y - b.x * a.y) / fabs(a.y - b.y);
     68     return l;
     69 }
     70 double dotdet(double x1, double y1, double x2, double y2)
     71 {
     72     return x1 * x2 + y1 * y2;
     73 }
     74 double dot(Point a, Point b, Point c)
     75 {
     76     return dotdet(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
     77 }
     78 int betweenCmp(Point a, Point b, Point c)
     79 {
     80     return dcmp(dot(a, b, c));
     81 }
     82 bool segcross(Point a, Point b, Point c, Point d, Point &p)
     83 {
     84     double s1, s2, s3, s4;
     85     int d1, d2, d3, d4;
     86     d1 = dcmp(s1 = cross(a, b, c));
     87     d2 = dcmp(s2 = cross(a, b, d));
     88     d3 = dcmp(s3 = cross(c, d, a));
     89     d4 = dcmp(s4 = cross(c, d, b));
     90     if((d1 ^ d2) == -2 && (d3 ^ d4 == -2))
     91     {
     92         p.x = (c.x * s2 - d.x * s1) / (s2 - s1);
     93         p.y = (c.y * s2 - d.y * s1) / (s2 - s1);
     94         return true;
     95     }
     96     if(d1 == 0 && betweenCmp(c, a, b) <= 0)
     97     {
     98         p = c;
     99         return true;
    100     }
    101     if(d2 == 0 && betweenCmp(d, a, b) <= 0)
    102     {
    103         p = d;
    104         return true;
    105     }
    106     if(d3 == 0 && betweenCmp(a, c, d) <= 0)
    107     {
    108         p = a;
    109         return true;
    110     }
    111     if(d4 == 0 && betweenCmp(b, c, d) <= 0)
    112     {
    113         p = b;
    114         return true;
    115     }
    116     return false;
    117 }
    118 
    119 bool CrossPoint(const Line &la, const Line &lb, Point &p)
    120 {
    121     return segcross(la.s, la.e, lb.s, lb.e, p);
    122 }
    123 bool Parallel(const Line &la, const Line &lb)
    124 {
    125     return !dcmp( (la.e.x - la.s.x) * (lb.e.y - lb.s.y) -
    126                   (la.e.y - la.s.y) * (lb.e.x - lb.s.x) );
    127 }
    128 double PolygonArea(vector<int> p)
    129 {
    130     if(p.size() < 4) return 0.0;
    131     double s = ap[p[0]].y * (ap[p[p.size() - 2]].x - ap[p[1]].x);
    132     for(int i = 1; i < p.size() - 1; ++ i)
    133         s += ap[p[i]].y * (ap[p[i - 1]].x - ap[p[i + 1]].x);
    134     return fabs(s * 0.5);
    135 }
    136 inline double CalLen(double a, double b)
    137 {
    138     return sqrt(a * a + b * b);
    139 }
    140 inline double CalDis(Point a, Point b)
    141 {
    142     return CalLen(a.x - b.x, a.y - b.y);
    143 }
    144 inline bool InCir(Point a, Point b)
    145 {
    146     return dcmp(CalDis(a, b) - b.r) < 0;
    147 }
    148 inline bool OnCir(Point a, Point b)
    149 {
    150     return dcmp(CalDis(a, b) - b.r) == 0;
    151 }
    152 double DisPtoL(Point p, Point a, Point b)
    153 {
    154     return fabs(cross(p, a, b)) / CalDis(a, b);
    155 }
    156 bool EqualPoint(Point a, Point b)
    157 {
    158     return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
    159 }
    160 bool SegIntersCircle(Point a, Point b, Point c)
    161 {
    162     Point t = c;
    163     t.x += a.y - b.y;
    164     t.y += b.x - a.x;
    165     return cross(a, c, t) * cross(b, c, t) < eps &&
    166            DisPtoL(c, a, b) - c.r < -eps;
    167 }
    168 bool JudgePiece(int i, vector<int> ps)
    169 {
    170     int j, k, cnt = 0;
    171     for(j = 1; j < ps.size(); ++ j)
    172     {
    173         if(InCir(ap[ps[j]], c[i])) return true;
    174         else if(OnCir(ap[ps[j]], c[i])) ++ cnt;
    175     }
    176     if(cnt >= 2) return true;
    177     for(j = 1; j < ps.size(); ++ j)
    178         for(k = j + 1; k < ps.size(); ++ k)
    179         {
    180             if(SegIntersCircle(ap[ps[j]], ap[ps[k]], c[i]))
    181                 return true;
    182         }
    183     for(j = 1; j < ps.size(); ++ j)
    184         if(cross(ap[ps[j - 1]], ap[ps[j]], c[i]) < -eps) return false;
    185     return true;
    186 }
    187 void FindPiece(int s0, int s1)
    188 {
    189     vector<int> ps;
    190     int i, j, nex = s1, ori = s0;
    191     double s;
    192     ps.push_back(s0);
    193     ps.push_back(s1);
    194     while(nex != ori)
    195     {
    196         nex = -1;
    197         for(i = 0; i < adjp[s1].size(); ++ i)
    198         {
    199             if(EqualPoint(ap[adjp[s1][i]], ap[s0])) continue;
    200             if(cross(ap[s0], ap[s1], ap[adjp[s1][i]]) > -eps &&
    201                     (nex == -1 || cross(ap[s1], ap[nex], ap[adjp[s1][i]]) > eps))
    202                 nex = adjp[s1][i];
    203         }
    204         if(nex != -1 && (!visp[nex] || nex == ori))
    205             ps.push_back(nex);
    206         else return;
    207         s0 = s1, s1 = nex;
    208     }
    209     s = PolygonArea(ps);
    210     if(!dcmp(s)) return;
    211     for(i = 0; i < m; ++ i)
    212         if(JudgePiece(i, ps))
    213             ans[i].push_back(s);
    214 }
    215 
    216 bool cmp(const int &a, const int &b)
    217 {
    218     if(dcmp(ap[a].x - ap[b].x) == 0)
    219         return ap[a].y < ap[b].y;
    220     return ap[a].x < ap[b].x;
    221 }
    222 int main()
    223 {
    224     int i, j, pnum;
    225     double sx, sy, ex, ey;
    226     while(scanf("%d%d%d%d", &n, &m , &L, &W), n | m | L | W)
    227     {
    228         l.clear();
    229         n += 4;
    230         M.clear();
    231         ap.clear();
    232         memset(visp, 0, sizeof(visp));
    233         l.push_back(SetLine(MakePoint(0, 0), MakePoint(L, 0)));
    234         l.push_back(SetLine(MakePoint(L, 0), MakePoint(L, W)));
    235         l.push_back(SetLine(MakePoint(L, W), MakePoint(0, W)));
    236         l.push_back(SetLine(MakePoint(0, W), MakePoint(0, 0)));
    237         for(i = 4; i < n; ++ i)
    238         {
    239             scanf("%lf%lf%lf%lf", &sx, &sy, &ex, &ey);
    240             l.push_back(SetLine(MakePoint(sx, sy), MakePoint(ex, ey)));
    241         }
    242         for(i = 0; i < m; ++ i)
    243             scanf("%lf%lf%lf", &c[i].x, &c[i].y, &c[i].r), ans[i].clear();
    244         for(i = 0; i < n; ++ i) lp[i].clear();
    245         for(i = pnum = 0; i < n; ++ i)
    246             for(j = i + 1; j < n; ++ j)
    247             {
    248                 Point tmp;
    249                 if(CrossPoint(l[i], l[j], tmp))
    250                 {
    251                     if(!M.count(tmp))
    252                         adjp[pnum].clear(), M[tmp] = pnum ++, ap.push_back(tmp);
    253                     lp[i].push_back(M[tmp]);
    254                     lp[j].push_back(M[tmp]);
    255                 }
    256             }
    257         for(i = 0; i < n; ++ i)
    258         {
    259             sort(lp[i].begin(), lp[i].end(), cmp);
    260             for(j = 1; j < lp[i].size(); ++ j)
    261             {
    262                 if(!EqualPoint(ap[lp[i][j]], ap[lp[i][j - 1]]))
    263                 {
    264                     adjp[lp[i][j]].push_back(lp[i][j - 1]);
    265                     adjp[lp[i][j - 1]].push_back(lp[i][j]);
    266                 }
    267             }
    268         }
    269         for(i = 0; i < pnum; ++ i)
    270         {
    271             if(!visp[i])
    272             {
    273                 visp[i] = true;
    274                 for(j = 0; j < adjp[i].size(); ++ j)
    275                     if(!visp[adjp[i][j]])FindPiece(i, adjp[i][j]);
    276             }
    277         }
    278         for(i = 0; i < m; ++ i)
    279         {
    280             sort(ans[i].begin(), ans[i].end());
    281             printf("%d", ans[i].size());
    282             for(j = 0; j < ans[i].size(); ++ j)
    283                 printf(" %.2f", ans[i][j]);
    284             printf("\n");
    285         }
    286         printf("\n");
    287     }
    288     return 0;
    289 }

     

     

  • 相关阅读:
    7.3形成团队结构
    第7章 设计构架
    第6章 空中交通管制:高可用性设计案例分析
    5.5安全性战术
    第5章实现质量属性
    4..4.7 使用一般场景进行沟通的概念
    4.4.3性能
    第II部分创建构架
    3.3.2使用结构
    docker容器互联
  • 原文地址:https://www.cnblogs.com/CSGrandeur/p/2659131.html
Copyright © 2011-2022 走看看