ZOJ - 3993-Safest Buildings

题目链接

题意:

给你一个圆形区域和他的半径,在这个区域内会重新刷新一个区域(完全包含,可内切),再给你区域内的n个点,求这些点包含在新区域内的概率最大的点有哪些,全部输出。

思路:

首先判断刷新区域半径r和原区域半径R的大小,画图可知,以(0,0)为原点|r*2-R|为半径的圆内的点在新区域内的概率都相等,如果没有这些点,那么就找离原点最近的点。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int N=2e5+5;
const int mod=1e9+7;
const int inf=0x7fffffff;
const double pi=3.1415926535;
using namespace std;
struct Q
{
    int x,y,z;
}q[N];
signed main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,m,r,mi=inf;
        vector<int>p;
        cin>>n>>m>>r;
        for(int i=0;i<n;i++)
        {
            cin>>q[i].x>>q[i].y;
            q[i].z=q[i].x*q[i].x+q[i].y*q[i].y;
            mi=min(mi,q[i].z);
        }
        if((r*2-m)*(r*2-m)>=mi)
        {
            for(int i=0;i<n;i++)
            {
                if(q[i].z<=(r*2-m)*(r*2-m))
                {
                    p.push_back(i+1);
                }
            }
            cout<<p.size()<<endl;
            for(int i=0;i<p.size();i++)
            {
                cout<<p[i]<<" ";
            }
            cout<<endl;
        }
        else
        {
            for(int i=0;i<n;i++)
            {
                if(q[i].z==mi)
                {
                    p.push_back(i+1);
                }
            }
            cout<<p.size()<<endl;
            for(int i=0;i<p.size();i++)
            {
                cout<<p[i]<<" ";
            }
            cout<<endl;
        }
        p.clear();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ACkingdom/article/details/106841994
ZOJ