zoukankan      html  css  js  c++  java
  • codeforces 814D An overnight dance in discotheque

    题目链接:http://codeforces.com/contest/814/problem/D

    题意:有n个人跳舞,然后每个人跳舞的区域是一个圆,圆与圆不想交。然后现在把这些人分成白天和黑夜跳舞的两批。如果一个人跳舞被覆盖奇数次,他的面积就需要被减去,被覆盖偶数次他的面积就会被加上,然后现在问你跳舞合适的最大面积是多少。

    分析:英语不好,题意看了好久才懂,其实将道理这道题跟着题意走就行了。首先需要确定每个圆与其他圆之间的关系,是否被覆盖,即包含。覆盖奇数次加上,偶数次减去,那么我肯定尽量加上大圆,减去小圆。我们可以记录每个圆可以覆盖的圆入队列,并且记录可以覆盖每个圆的最小圆是谁。对于一个大圆,他所包含的所有圆构成的面积最大就是他的面积加上奇数覆盖的面积-偶数覆盖圆的面积。可以bfs求,然后只有直接覆盖某个圆的时候才可以入队列。圆面积按大小排序,然后i如果覆盖j,g[i].push_back(j),然后枚举1到n各个圆,bfs,如果面积已经被计算过,return0,求和即可。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 struct st{
     5     long long x,y,r;
     6     int id,cnt;
     7 }a[1005];
     8 vector<st>g[1005];
     9 int d[1005];
    10 double pi=3.1415926535898;
    11 int vis[1005];
    12 
    13 long long bfs(int x){
    14     queue<st >q;
    15     if(vis[x]==1) return 0;
    16     q.push(a[x]);
    17     vis[x]=1;
    18     long long sum=a[x].r*a[x].r;
    19     while(!q.empty()){
    20         st b=q.front();
    21         q.pop();
    22         int l=g[b.id].size();
    23         for(int i=0;i<l;i++){
    24             if(d[g[b.id][i].id]==b.id){
    25                 g[b.id][i].cnt=b.cnt+1;
    26                 vis[g[b.id][i].id]=1;
    27                 if(g[b.id][i].cnt%2==1) sum+=g[b.id][i].r*g[b.id][i].r;
    28                 else sum-=g[b.id][i].r*g[b.id][i].r;
    29                 q.push(g[b.id][i]);
    30             }
    31         }
    32     }
    33     return sum;
    34 }
    35 bool cmp(st a,st b){
    36     return a.r>b.r;
    37 }
    38 int main(){
    39     int n;
    40     cin>>n;
    41     int x,y,r;
    42     for(int i=1;i<=n;i++){
    43         cin>>a[i].x>>a[i].y>>a[i].r;
    44     }
    45     memset(d,0,sizeof(d));
    46     sort(a+1,a+1+n,cmp);
    47     for(int i=1;i<=n;i++){
    48         a[i].id=i;
    49         a[i].cnt=0;
    50     }
    51     for(int i=1;i<=n;i++){
    52         for(int j=i+1;j<=n;j++){
    53             if(((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y))<(a[i].r+a[j].r)*(a[i].r+a[j].r)){
    54                 g[i].push_back(a[j]);
    55                 d[j]=i;
    56             }
    57         }
    58     }
    59     memset(vis,0,sizeof(vis));
    60     long long result=0;
    61     for(int i=1;i<=n;i++){
    62         result+=bfs(i);
    63     }
    64     printf("%.8lf
    ",pi*result);
    65     return 0;
    66 }
    View Code
  • 相关阅读:
    POJ 2187 Beauty Contest(凸包+旋转卡壳)
    POJ 3845 Fractal(计算几何の旋转缩放)
    POJ 1755 Triathlon(线性规划の半平面交)
    POJ 2540 Hotter Colder(半平面交)
    POJ 3525/UVA 1396 Most Distant Point from the Sea(二分+半平面交)
    POJ 3348 Cows(凸包+多边形面积)
    POJ 1228 Grandpa's Estate(凸包唯一性判断)
    POJ 2826 An Easy Problem?!(线段交点+简单计算)
    如何在ARC代码中混编非ARC代码
    给view 添加事件
  • 原文地址:https://www.cnblogs.com/ls961006/p/6971844.html
Copyright © 2011-2022 走看看