• P3928奶酪


    传送

    今天早晨,神志不清的我决定拿头过这道题

    终于在wa了6次之后过了

    emm  明明都是一些细节自己却注意不到啊啊啊不能再颓了!!!!!!!!!!!!

    好了回归正题

    首先我们要开long long

    其次我们来说一说思路

    大佬xcg讲了两种做法

    一.搜索

    不好想不好写,比第二种算法快

    洛谷标签说是广搜,但这个题深搜会比广搜快,因为这里是判断有没有解,而不是让你求最短路

    如果要求最短路怎么办?拿头过三维迪杰斯特拉我也不知道

    所以我们不讨论怎么求最短路(没有杠精)

    我们怎么搜呢?

    当然是从下表面开始了(当然也可以从上表面开始,看能否通到下表面,更可以看上下表面哪个洞少就从那个开始搜)

    在搜索过程中,就不断找到与当前点相通的点。同时又因为只是判断有没有解,所以只要找到解,就可以直接返回,然后让上一层的程序也返回。这可以用一个标记做到。

    问题来了,怎么判断两个洞是否相通?

    我们计算两个洞的球心的距离,如果它<=2*r,则证明这两个洞相交或者相切(我也不知道jerry是怎么在相切的时候穿过这一个接触的点的),当等于时,是相切。否则,就不相通。

    与底部相通:判断洞的球心的高度-r是否<=0(不是<=h)(我也不知道手残打出来的为什么还有30分)

    与顶部相通:球心高度+r>=h

    拿头硬过的代码:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll read()
    {
        char ch=getchar();
        ll x=0;bool f=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')f=1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=(x<<3)+(x<<1)+(ch^48);
            ch=getchar();
        }
        return f?-x:x;
    }
    ll t,n,h,r;
    bool bj,vis[1009];
    struct qiu{
        ll x,y,z;
    }p[1009];
    bool cmp(qiu a,qiu b)//一个优化退化:按照所有球心的高度进行排序,如果从某个球开始就不与底部相通,则后面的球都不会与底部相通(据lz实测会慢emmmm)
    {
        return a.z<b.z;
    }
    double jl(qiu a,qiu b)
    {
        return sqrt((double)((a.x-b.x)*(a.x-b.x))+(double)((a.y-b.y)*(a.y-b.y))+(double)(a.z-b.z)*(a.z-b.z));
    }
    void dfs(ll k)
    {
        if(p[k].z+r>=h)
        {
            bj=1;//bj标记有解
            return;
        }
        for(int i=1;i<=n;i++)
        {
            if(bj)return;//若有解则不继续搜索
            if(jl(p[k],p[i])<=2.0*r&&!vis[i])
            {
                vis[i]=1;
                dfs(i);
            }
        }
    }
    int main()
    {
    
        t=read();
        for(ll i=1;i<=t;i++)
        {
            memset(vis,0,sizeof(vis));
            bj=0;
            n=read();h=read();r=read();
            for(ll j=1;j<=n;j++)
             p[j].x=read(),p[j].y=read(),p[j].z=read();
            sort(p+1,p+1+n,cmp);
            for(int j=1;j<=n;j++)
            {
                if(bj)break;
                if(p[j].z-r<=0)//可别手残了
                {
                    vis[j]=1;
                    dfs(j);
                }
                else break;
            }    
            if(!bj)printf("No
    ");
            else printf("Yes
    ");
        }
    }
  • 相关阅读:
    javaWeb学习笔记之关于重定向和请求转发的区别
    javaWeb学习笔记之关于Servlet文件下载
    javaWeb学习笔记之关于http
    javaWeb学习笔记之关于tomcat
    小程序订阅消息推送
    Oracle数据库序列的相关问题
    将本地项目push到gitlab仓库中
    面试之BI-SQL--table转换[2]
    面试之BI-SQL--table转换
    面试之C#--垃圾回收器什么时候回收?
  • 原文地址:https://www.cnblogs.com/lcez56jsy/p/11137425.html
Copyright © 2020-2023  润新知