AtCoder Beginner Contest 356 G. Freestyle(凸包+二分)

题目

思路来源

quality代码

题解

对n个泳姿点(ai,bi)建凸包,实际上是一个上凸壳,

对于询问(ci,di)来说,抽象画一下这个图,箭头方向表示询问向量

按x轴排增序,并且使得后面的y不小于前面的y,因为总可以多耗费体力达到相同的米数

新增一个点(0,0),新增一个点(1e9+1,y),其纵坐标与最后一个点纵坐标相同

对于询问的向量,求它与上凸壳的交点,显然用这个方向的向量是最优的

1. 如果询问的向量在上凸壳第一个点逆时针方向,无解

2. 如果与上凸壳有交点,

显然这个封闭图形内的点都是可以用各种泳姿1s凑出来的,那么交点方向最优,

只需看(ci,di)中的di,是交点处的纵坐标的几倍即可,答案即为这个倍数

3. 如果向量与竖直的这条边有交点,那么最后相当于多耗费体力的情况下1s也可以跑这么多米

那么,两条直线还是有交点的,只是向量与水平直线的交点,

实际用的仍然是交点这个向量,只是实际的含义是y相同的情况下多耗费了体力

然后qls的二分写的就很妙,统一了这三种情况,以及交点恰好是凸包的一个点的情况

我写的就很不优雅,需要讨论三种情况,判断l=0,l=n-1

代码1(qls)

#include<bits/stdc++.h>
#include<iostream>
using namespace std;
typedef long long ll;
typedef long double db;
struct Point
{
    ll x,y;
    int id;
    Point() {}
    Point(ll _x,ll _y):x(_x),y(_y) {}
    Point operator - (const Point& t)const
    {
        return Point(x-t.x,y-t.y);
    }
    ll operator * (const Point& t)const
    {
        return x*t.y-y*t.x;
    }
};
vector<Point> Graham(vector<Point> p)
{
    p.insert(p.begin(),Point(0,0));
    sort(p.begin(),p.end(),[](const Point& lhs,const Point& rhs)
    {
        return lhs.x==rhs.x ? lhs.y<rhs.y : lhs.x<rhs.x;
    });
    for(size_t i=1; i<p.size(); i++)
        p[i].y=max(p[i].y,p[i-1].y);
    p.emplace_back(1000000001,p.back().y);
    vector<Point> res;
    for(auto& t : p)
    {
        while(res.size()>1 && (t-res.back())*(t-res[res.size()-2])<=0)res.pop_back();
        res.push_back(t);
    }
    res.erase(res.begin());
    return res;
}
int main()
{
    int n;
    scanf("%d",&n);
    vector<Point> p(n);
    for(int i=0; i<n; i++)
        scanf("%lld%lld",&p[i].x,&p[i].y);
    p=Graham(p);
    n=p.size();
    int q;
    scanf("%d",&q);
    while(q--)
    {
        Point que;
        scanf("%lld%lld",&que.x,&que.y);
        if(que*p[0]<0)
        {
            printf("-1\n");
            continue;
        }
        int l=0,r=n-2;//l<=r+1
        while(l<r)//>0 =0 <0 或>0 <0渐变
        {
            int m=(l+r+1)/2;
            if(que*p[m]>0)l=m;
            else r=m-1;
        }
        db k1=1.0L*(p[l+1].y-p[l].y)/(p[l+1].x-p[l].x);
        db b1=p[l].y-k1*p[l].x;
        db k2=1.0L*que.y/que.x;
        db x=b1/(k2-k1),y=k2*x;
        printf("%.18Lf\n",que.y/y);
    }
    return 0;
}

代码2(我的二分)

#include<bits/stdc++.h>
#include<iostream>
using namespace std;
typedef long long ll;
typedef long double db;
struct Point
{
    ll x,y;
    int id;
    Point() {}
    Point(ll _x,ll _y):x(_x),y(_y) {}
    Point operator - (const Point& t)const
    {
        return Point(x-t.x,y-t.y);
    }
    ll operator * (const Point& t)const
    {
        return x*t.y-y*t.x;
    }
};
vector<Point> Graham(vector<Point> p)
{
    p.insert(p.begin(),Point(0,0));
    sort(p.begin(),p.end(),[](const Point& lhs,const Point& rhs)
    {
        return lhs.x==rhs.x ? lhs.y<rhs.y : lhs.x<rhs.x;
    });
    for(size_t i=1; i<p.size(); i++)
        p[i].y=max(p[i].y,p[i-1].y);
    p.emplace_back(1000000001,p.back().y);
    vector<Point> res;
    for(auto& t : p)
    {
        while(res.size()>1 && (t-res.back())*(t-res[res.size()-2])<=0)res.pop_back();
        res.push_back(t);
    }
    res.erase(res.begin());
    return res;
}
int main()
{
    int n;
    scanf("%d",&n);
    vector<Point> p(n);
    for(int i=0; i<n; i++)
        scanf("%lld%lld",&p[i].x,&p[i].y);
    p=Graham(p);
    n=p.size();
    int q;
    scanf("%d",&q);
    while(q--)
    {
        Point que;
        scanf("%lld%lld",&que.x,&que.y);
        if(que*p[0]<0)
        {
            printf("-1\n");
            continue;
        }
        int l=0,r=n-1;
        while(l<=r){
            int m=(l+r)/2;
            if(que*p[m]>0)l=m+1;
            else r=m-1;
        }
        l--;
        if(l<0)l=0;
        if(l==n-1)l--;
        //if(l==n-1)l--;
        db k1=1.0L*(p[l+1].y-p[l].y)/(p[l+1].x-p[l].x);
        //k1=0 b1=5 k2=8/6 x=5/(8/6)=30/8 y=30/6=5 
        db b1=p[l].y-k1*p[l].x;
        db k2=1.0L*que.y/que.x;
        db x=b1/(k2-k1),y=k2*x;
        printf("%.18Lf\n",que.y/y);
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/694620.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ThreadCache线程缓存

一.ThreadCache整体结构 1.基本结构 定长内存池利用一个自由链表管理释放回来的固定大小的内存obj。 ThreadCache需要支持申请和释放不同大小的内存块&#xff0c;因此需要多个自由链表来管理释放回来的内存块.即ThreadCache实际上一个哈希桶结构&#xff0c;每个桶中存放的都…

LLM的基础模型8:深入注意力机制

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…

SpringBoot之静态资源

默认静态资源路径 classpath:/META-INF/resources/classpath:/resources/classpath:/static/classpath:/public/ 静态资源路径下的文件&#xff0c;可以通过根目录访问 resources 文件夹的文件如下图所示&#xff1a; 启动项目&#xff0c;分别访问以下路径&#xff1a; ht…

STM32 proteus + STM32Cubemx仿真教程(第一课LED教程)

文章目录 前言一、STM32点亮LED灯的原理1.1GPIO是什么1.2点亮LED灯的原理 二、STM32Cubemx创建工程三、proteus仿真电路图四、程序代码编写1.LED灯操作函数介绍HAL_GPIO_WritePin函数原型参数说明示例代码 HAL_GPIO_TogglePin函数原型参数说明示例代码 2.代码编写3.烧写程序 总…

微服务开发与实战Day04 - 网关路由和配置

一、网关路由 网关&#xff1a;就是网络的关口&#xff0c;负责请求的路由、转发、身份校验。 在SpringCloud中网关的实现包括两种&#xff1a; 1. 快速入门 Spring Cloud Gateway 步骤&#xff1a; ①新建hm-gateway模块 ②引入依赖pom.xml(hm-gateway) <?xml version…

在VSCode中安装python

引言 Python 是一种广泛使用的高级编程语言&#xff0c;因其易学、易用、强大而受到欢迎。它由 Guido van Rossum 于 1991 年首次发布&#xff0c;并以简洁的语法和丰富的库生态系统而著称。 以下是 Python 的一些关键特点和优势&#xff1a; 关键特点 易于学习和使用&#x…

vue28:组件化开发和根组件

简单写个点击事件 <template> <div class"app"><div class"box" click"fn"></div></div> </template><script> export default {//导出当前组件的配置项//里面可以提供 data methods computed wat…

解决PyQt5中柱状图上显示的数值为带e的科学计数法

PyQt5生成柱状图的代码参考&#xff1a;PyQt5 QtChart-柱状图 参照上述文章&#xff0c;生成柱状图后&#xff0c;数值较大或较小情况下会导致柱状图上显示数值为带e的科学计数法&#xff0c;这样会影响数值的识别&#xff1a; 经过分析QBarSet方法得到解决方法&#xff1a;需…

基于stm32最小版的超声波测距模块

目录 一、模块准备 二、HC-SR04模块原理解释 三、程序完整代码 四、烧录结果 总结 一、模块准备 STM32F103C8T6 HC-SR04 ST-Link&#xff08;其他烧录器也可以&#xff09; 0.96寸OLED屏幕&#xff08;非必须&#xff0c;仅供显示测距结果&#xff0c;可以使用串口助手代替…

【Git】详解本地仓库的创建、配置以及工作区、暂存区、版本库的认识

一、创建本地仓库 需要将本地仓库放在一个目录下&#xff0c;所以在创建本地仓库之前&#xff0c;应该先创建一个目录&#xff0c;再进入这个目录&#xff1a; 在这个目录中创建一个本地仓库&#xff1a; git init 创建完成后&#xff0c;我们就会发现当前目录下多了一个.git…

【Redis学习笔记04】Jedis客户端(上)

Java客户端操作Redis Java生态丰富&#xff0c;自定义的客户端非常多&#xff0c;常见的有Jedis、Lettuce、以及Spring整合后的RedisTemplate&#xff0c;但是对于初学者而言&#xff0c;从Jedis开始入门学习是非常容易上手的&#xff0c;因为Jedis中的API与原生Redis命令高度…

DT-MIL:用于组织病理学图像的MIL方法

学习信息表示对于组织病理学图像的分类和预测任务至关重要。由于图像大小巨大&#xff0c;通常使用多实例学习&#xff08;MIL&#xff09;方案来处理整张组织病理学图像&#xff08;whole-slide histopathological image&#xff09;。然而&#xff0c;MIL的弱监督性质导致了学…

阿里云平台产品创建过程 网页端界面 手机APP

云平台产品创建 登录后选择 产品-物联网-物联网平台&#xff1a; 进入后选择 公共示例-立即试用&#xff1a; 选择 公共示例&#xff1a; 选择 设备管理-产品-创建产品&#xff1a; 产品名称: 传感器 所属品类&#xff1a;自定义品类 节点类型&#xff1a;直连设备 联网方式…

【JsDoc】JsDoc用法 | 巧妙用法

type type {other} other 接收表达式或字符 1、数组代码提示 1、效果图 1、码 /*** type {Array.<play|paush|next>} */ let music []2、字符串提示 2、效果图 2、码 /*** type {a|b|c}*/ let str

UI学习(二)

UI学习&#xff08;二&#xff09; 文章目录 UI学习&#xff08;二&#xff09;布局子视图手动布局自动布局 导航控制器导航控制器基础导航控制器的切换导航栏工具栏 分栏控制器分栏控制器协议部分的内容UITableView基础部分相关的协议函数高级协议与单元格 多界面传值 布局子视…

零基础入门篇①⑦ Python可变序列类型--集合

Python从入门到精通系列专栏面向零基础以及需要进阶的读者倾心打造,9.9元订阅即可享受付费专栏权益,一个专栏带你吃透Python,专栏分为零基础入门篇、模块篇、网络爬虫篇、Web开发篇、办公自动化篇、数据分析篇…学习不断,持续更新,火热订阅中🔥专栏限时一个月(5.8~6.8)重…

csdn上传图片失败解决办法

今天下午写笔记&#xff0c;上传图片的时候总是出现图片上传不成功。查询了下解决方案&#xff1a; C:\Windows\System32\drivers\etc &#xff0c;使用管理员打开hosts文件加入&#xff1a; 49.7.22.7 csdn-img-blog.oss-cn-beijing.aliyuncs.com保存之后&#xff0c;&#x…

C++期末复习提纲(血小板)

目录 1.this指针 2.静态成员变量 3.面向对象程序设计第一阶段 4.面向对象程序设计第二阶段 5.面向对象程序设计第三阶段 6.简答题 &#xff08;1&#xff09;拷贝构造函数执行的三种情况&#xff1a; &#xff08;2&#xff09;虚析构函数的作用&#xff1a; &#xff…

eNSP学习——RIP故障处理

目录 主要命令 原理概述 实验目的 实验内容 实验拓扑 实验编址 实验步骤 1、导入设备预配置 2、排除R1与R2间的故障 3、排除R1与R3间的故障 需要eNSP各种配置命令的点击链接自取:华为eNSP各种设备配置命令大全PDF版_ensp配置命令大全资源-CSDN文库 主要命令 //检查…