0
点赞
收藏
分享

微信扫一扫

2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】


​​题目传送门​​

题目描述

umi对弓道非常痴迷。
有一天,她在研究一个射箭问题:
在一个无限大的平面中,她站在 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_i++ 这个坐标。
2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_i++_02 个靶子,第 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_坐标轴_03 个靶子的坐标是 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_双指针_04
umi准备在 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_算法_05 轴或 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_坐标轴_06 轴上放置一块挡板来挡住弓箭的轨迹,使得她可以射中的靶子数量不超过 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_算法_07 个。
她想知道挡板的最短长度是多少?

注1:假定弓箭的轨迹是起点为umi坐标、长度无穷大的射线。umi和靶子的体积可以无视。挡板的边缘碰到弓箭轨迹也可视为挡住弓箭。

注2:挡板不能弯折,起始和终点必须在同一坐标轴上。

输入描述:

第一行两个整数 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_算法_082020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_坐标轴_09 ,代表umi的坐标。
第二行两个正整数 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_i++_022020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_算法_07 ,分别代表靶子的总数量、放置挡板后可射中靶子的最大值。
接下来的 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_i++_02 行,每行两个整数 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_双指针_132020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_i++_14 。代表每个靶子的坐标。
保证没有任何一个点在坐标轴上(无论umi还是靶子),保证没有任何两点重合。
2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_i++_15

输出描述:

若无论如何无法保证可以射中的靶子数量不超过 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_算法_07 个,则输出 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_i++_17
否则输出挡板的最小长度。如果你和正确答案的误差不超过 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_i++_18,则视为答案正确。
示例1

输入

1 1
2 0
-1 2
-2 1

输出

0.50000000

说明

umi要保证能射中的靶子不超过0个,即全部挡住。在y轴上选区间[1,1.5]放置一个长度为0.5的挡板即可。

题解

  • 首先确定umi所在位置的象限。很明显同一象限的点是不可能用挡板挡掉的,对于剩下的点找出线段和2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_坐标轴_19轴或2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_双指针_20轴的交点,统计坐标位置(如果存在交点的话)。
    之后双指针维护2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_坐标轴_19轴上或者2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_双指针_20轴挡住2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_算法_23个点的挡板长度最小值。注意2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_坐标轴_19轴和2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_双指针_20
  • 2020牛客寒假算法基础集训营1——C.umi和弓道【计算几何 & 贪心 & 双指针】_坐标轴_26

AC-Code

#include <bits/stdc++.h>
using namespace std;

vector<double> vx,vy;
int main(){
double X0,Y0;
while(cin >> X0 >> Y0){
vx.clear(), vy.clear();
int n, k; cin >> n >> k;
for(int i = 0; i < n; ++i){
double x, y; cin >> x >> y;
double k = (y-Y0)/(x-X0);
if(x * X0 < 0) vy.push_back(y-k*x);
if(y * Y0 < 0) vx.push_back(x-y/k);
}
sort(vx.begin(), vx.end());
sort(vy.begin(), vy.end());
double ans = 1e18;
k = n - k; // 需要挡住 k 个
for(int i = k-1; i < vx.size(); i++) ans = min(ans, vx[i] - vx[i-k+1]);
for(int i = k-1; i < vy.size(); i++) ans = min(ans, vy[i] - vy[i-k+1]);
if(ans == 1e18) cout << "-1" << endl;
else printf("%.8f\n", ans);
}
}


举报

相关推荐

0 条评论