zoukankan      html  css  js  c++  java
  • 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;
    } 
  • 相关阅读:
    Neko's loop HDU-6444(网络赛1007)
    Parameters
    SETLOCAL
    RD / RMDIR Command
    devenv 命令用法
    Cannot determine the location of the VS Common Tools folder.
    'DEVENV' is not recognized as an internal or external command,
    How to change Visual Studio default environment setting
    error signing assembly unknown error
    What is the Xcopy Command?:
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4385549.html
Copyright © 2011-2022 走看看