-
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-10