• XMOJ 1133: 膜拜大牛 计算几何/两圆相交


    1133: 膜拜大牛

    Time Limit: 1 Sec  Memory Limit: 131072KiB
    Submit: 9619  Solved: 3287

    题目连接

    http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1133

    Description

    由于wywcgs是个很菜的菜鸟,所以每到一个新的地方,他都必须去膜拜当地的大牛。但是大牛们都没空理他,所以无可奈何之下,wywcgs只能寻找其他 的办法。为了一次Orz到更多的大牛,他想到了一个好方法,就是在地图上找到每位大牛所在的位置,然后对着地图Orz,这样就可以膜拜到大牛了。我们可以 假设wywcgs的脑袋是半径为r的圆形。在Orz的时候,只要wywcgs的脑袋覆盖到了某位大牛所在的位置(边界也算覆盖),就算是Orz到了该位大 牛。每位大牛都有一个“NB度”,wywcgs当然想尽量能够Orz到更加NB的大牛,所以他想通过一次Orz,让自己Orz到的大牛的NB度的和最大。 由于他实在是太菜了,根本不知道该在哪里Orz才能达到这个效果。你能帮帮他吗?

    Input

    输入由多组数据组成。第一行是一个整数T(1<=T<=20),数据的组数。
      下面T组数据,每一组数据的第一行为一个正整数N(1<=N<=50),代表当地大牛的数量。接下来N行,每行有三个整数Xi Yi Wi(-20,000<=Xi,Yi<=20,000, 0<=Wi<=10^6),分别表示第i位大牛在地图上的横纵坐标和它的NB度,这个位置可以看成是一个面积为0的点。每组数据的最后一行是一个整数R(1<=R<=20,000),表示wywcgs脑袋的半径。

    Output

    总共输出T个整数。对每组数据,输出wy一次所能Orz到的大牛的最大NB度的和。

    Sample Input

    2
    4
    0 -10 1
    0 10 1
    -10 0 1
    10 0 1
    10
    4
    0 -10 1
    0 10 1
    -10 0 1
    10 0 1
    8

    Sample Output

    4
    2

    HINT


    题解:

    圆交点的最大值,转化为圆弧被多少个圆覆盖的问题

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 200001
    #define mod 10007
    #define eps 1e-9
    //const int inf=0x7fffffff;   //无限大
    const int inf=0x3f3f3f3f;
    /*
    inline ll read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    */
    //**************************************************************************************
    
    
    const double  eps = 1e-9;
    const double pi = acos(-1.0);
    const int N = 555;
        
    struct point
    {
        double x,y;
        int nb;
    }p[N];
        
    int n,r;
        
    struct alpha
    {
        double v;
        int nb;
        int flag;
        bool friend operator <(const alpha &a,const alpha &b)
        {   
            if(abs(a.v-b.v)<=eps)
                return a.flag>b.flag;
            else
                return a.v < b.v;
        }
    }alp[N * 2];
        
    double dis(point a, point b)
    {
        return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    }
        
    void solve(double R)
    {
        int ans = 0;
        double theta,phi,dist;
        int i,j;
        for( i = 0;i < n;i++)
        {
            int k = 0;
            for( j = 0;j < n;j++)
            {
                if(i == j) continue;
                dist = dis(p[i],p[j]);
                if(dist - 2.0 * R > eps)//判断是否有交点
                    continue;
                theta = atan2(p[j].y - p[i].y, p[j].x - p[i].x);//这条直线的斜率
                if(theta < eps)
                    theta += 2 * pi;
                phi = acos(dist / (2.0 * R));
                alp[k].v = theta - phi + 2 * pi;
                alp[k].flag = 1;
                alp[k].nb=p[j].nb;
      
                alp[k + 1].v = theta + phi + 2 * pi;
                alp[k + 1].flag = 0;
                alp[k+1].nb=p[j].nb;
                k += 2;
            }
            sort(alp,alp + k);
            int sum = p[i].nb;
            ans=max(sum,p[i].nb);
            for( j = 0;j < k;j++)
            {
                if(alp[j].flag)
                    sum +=alp[j].nb;
                else
                    sum -=alp[j].nb;
                if(sum > ans)
                    ans = sum;
            }
        }
        printf("%d
    ",ans );
    }
        
    int main()
    {
        int i,j,t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(i=0;i<n;i++)
            {
                int x,y;
                int nb;
                scanf("%d %d %d",&x,&y,&nb);
                p[i].x=double(x);
                p[i].y=double(y);
                p[i].nb=nb;
            }
            scanf("%d",&r);
            solve(double(r));
        }
        return 0;
    } 
  • 相关阅读:
    6.一个python-selenium的实战
    9.python-ini文件使用(读和写)
    4.表数据的操作-insert、delete
    5.数据库的查询-select
    2.自动化测试之python+selenium基础
    6.python中目录的操作
    sql如何先排序再去重
    hbase(0.94) get、scan源码分析
    Antlr 在 idea 中正确使用的方式
    某日看代码对代码可读性的思考
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4385549.html
Copyright © 2020-2023  润新知