本场比赛通过人数只有十几人的数学毒瘤题qwq。。关于此题讲解好像也不多,要先了解基本的弧度知识,初中蒟蒻瑟瑟发抖

在@Marco.L.T. dalao的帮助下,小蒟蒻勉强通过了本题(下面的代码是在Marco.L.T.代码的基础上稍微改进的)

先把代码放这qwq,等小蒟蒻完全弄懂了,会来不断完善本篇题解的!

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
struct node {
    double x,y,l,r;
} p[505];
inline bool cmp(node a,node b) {
    return a.l<b.l;
}
const double pi=acos(-1);//acos()是反余弦函数,cosπ = -1,所以π = acos(-1)。
double pl[505],pr[505],maxr[505],r;
int main() {
    int n,T,cnt,cnt2,ans,pos,tot;
    double d,dis,si,otg,t,tg;

    scanf("%d",&T);
    while(T--) {
        scanf("%d%lf",&n,&d),cnt=0;
        for (int x,y,i=1; i<=n; i++) {
            scanf("%d%d",&x,&y);
            dis=sqrt(x*x+y*y);//计算到原点距离
            if (dis<=d) continue;//由于射线都是以原点为端点,所以dis<=d则任一条射线都可覆盖到,略过此点

            si=d/dis,otg=si/sqrt(1-si*si);//计算可行的夹角区间(在这个区间内的射线到点(x,y)的距离都小于d,即可以覆盖到),otg是两条切线夹角的1/2(见下图))
            t=atan(otg),tg=atan2(y,x);//atan可返回数字的反正切值

            while(tg-t<0) tg+=2*pi;
            while(tg-t>2*pi) tg-=2*pi;//加减2pi就是保证所有角度在一圈以内(因为x+2pi和x表示的角度相同)
            p[++cnt]=(node) {
                x,y,tg-t,tg+t
            };
        }

        sort(p+1,p+cnt+1,cmp);

        if (cnt) {
            ans=cnt;//最多要cnt条射线
            for(int i=1; i<=cnt; i++) {
                cnt2=0;

                for (int j=i; j<=cnt; j++)
                    pl[++cnt2]=p[j].l,pr[cnt2]=p[j].r;
                for (int j=1; j<i; j++)
                    pl[++cnt2]=p[j].l+2*pi,pr[cnt2]=p[j].r+2*pi;

                pos=1,tot=0,maxr[cnt]=pr[cnt];
                for (int j=cnt-1; j; j--) maxr[j]=min(maxr[j+1],pr[j]);
                while(pos<=cnt) {

                    r=maxr[pos];
                    while(pos<=cnt && pl[pos]<=r) pos++;
                    tot++;
                }
                ans=min(ans,tot);
            }
            printf("%d\n",ans);
        } else puts("1"); //由于病毒数n>=0,如果病毒到圆心距离<=d,至少需要一条直线
    }
}