M - Safest Buildings ZOJ -概率+计算几何

  • M - Safest Buildings

  •  ZOJ - 3993 
  • 题意:“吃鸡”游戏,给出两个半径R,r,R表示第一次的大圈半径,r表示第二次的小圈半径。
  • 第一次大圈的圆心位于(0,0)。第二次小圈的圆心未知,但在大圈内,给你一个n,然后给出n个屋子的位置,
  • 问这些屋子中,第二次在小圈的概率最大的屋子有几个,都是哪些。
  • 思路:首先分析到新的小圆不会超出大圆的边界,所以小圆的圆心就会有一个圆形区域的范围。
  • 那么接着分析,距离小圆这个圆心所在的圆形区域的中心的距离决定了他们的概率不同,而中心就是(0,0)
  • 所以大部分点概率是按照距离圆心的距离来排序,但是有一部分点的概率是相同的就是就是所有可能的圆心覆盖的面积
  • 覆盖住这一部分的概率是相同的,找一个相同的临界条件,发现R=2*r时,原点(0,0)可能是100%被包含的。
  • #include<iostream>
    #include<cstring>
    #include<stdio.h>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define maxn 255555
    #define ll long long
    vector<int>qq;
    struct code
    {
        ll a,b,c;
        int id;
    } ss[100005];
    bool cmp(code a,code b)
    {
        return a.c<b.c;
    }
    int n;
    ll rr,r;
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            qq.clear();
            cin>>n>>rr>>r;
            for(int i=0; i<n; i++)
            {
                cin>>ss[i].a>>ss[i].b;
                ss[i].id=i+1;
                ss[i].c=ss[i].a*ss[i].a+ss[i].b*ss[i].b;
            }
            sort(ss,ss+n,cmp);
            for(int i=0; i<n; i++)
            {
                if(ss[i].c<=(rr-2*r)*(rr-2*r))
                    qq.push_back(ss[i].id);
                    else break;
            }
            if(qq.size()==0)
            {
                qq.push_back(ss[0].id);
                for(int i=1; i<n; i++)
                {
                    if(ss[i].c==ss[i-1].c)
                        qq.push_back(ss[i].id);
                    else break;
                }
            }
            cout<<qq.size()<<endl;
            int len=qq.size();
            sort(qq.begin(),qq.end());
            for(int i=0; i<len; i++)
            {
                if(i==0)
                    cout<<qq[i];
                else
                    cout<<" "<<qq[i];
            }
            cout<<endl;
        }
        return 0;
    }

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值