[CSP-S模拟测试]:导弹袭击(数学+凸包+单调栈)
题目背景
$Guess$准备向敌军阵地发起进攻了!$Guess$的武器是自动制导导弹。
然而在机房是不允许游戏的,所以班长$XZY$对游戏界面进行了降维打击,结果。。。
题目描述
众所周知,环境因素对导弹制导的效率影响是很大的。地图上总共有两种环境,暂且称为环境一和环境二。$Guess$有$n$种型号的导弹,每一种都有两个参数$a_i,b_i$,分别表示该型号导弹在两种环境下的恒定飞行速度。
然而,$Guess$攻击的距离和角度会经常调整,导弹预定轨迹上的地形也会随之变化。一维化以后,导弹预定轨迹可以看成一条长度不定的线段,其中经过环境一的长度为$A$,经过环境二的长度为$B$。
在不确定两种环境长度比重的情况下,$Guess$想知道,有哪几种型号的导弹是有用的。某种型号的导弹有用,当且仅当存在一对正实数$A,B$,使得该型号的总飞行时间为所有型号中最短的之一。
原题见:$[CF535E]Tavas\ and\ Pashmaks$
输入格式
第一行一个正整数$n$,表示型号总数。
接下来$n$行,第$i$行两个正整数$a_i,b_i$,分别表示$i$型导弹在环境一和环境二下的飞行速度。
输出格式
一行若干个正整数,从小到大输出每个有用的导弹型号的编号$i$,用单个空格隔开。
样例
样例输入:
7
6 6
5 7
3 13
4 12
2 13
12 4
3 13
样例输出:
1 3 4 6 7
数据范围与提示
样例解释:
取$A=12,B=12$时,型号$1,4,6$均用时最快,为$4$单位时间;
取$A=3,B=39$时,型号(参数相同)均用时最快,为$4$单位时间;
容易发现无论如何调整$A,B$,型号$2,5$用时均不是最快的(注意$A,B$为正实数)。
数据范围:
对于$10\%$的数据,$n\leqslant 2$;
对于$20\%$的数据,$n\leqslant 3$;
对于$40\%$的数据,$n\leqslant 300$;
对于另$20\%$的数据,$n\leqslant 3\times 10^4,a_i,b_i\leqslant 3\times 10^3$;
对于另$20\%$的数据,$n\leqslant 3\times 10^5,a_i,b_i\leqslant 3\times 10^4$;
对于$100\%$的数据,$n\leqslant 3\times 10^5,a_i,b_i\leqslant 10^9$。
题解
可以将每颗导弹看成是平面上的点$(\frac{1}{a_i},\frac{1}{b_i})$,这样问题就转化成了:给定$A,B$,最小化$z=Ax+By$($x,y$为顶点坐标)。
那么,每两个点都会形成一个一次函数,而对于所有一次函数,位于其下凸包上的点也就是能做贡献的点。
先将其按横坐标排序,再用一个单调栈维护这个下凸包就好了。
注意如果有两点斜率为正,那么位于右边的点肯定不会做贡献。
这道题卡了精度,所以算斜率的式子需要做如下化简:
$\Large \begin{array}{rl} & \frac{\frac{1}{b_j}-\frac{1}{b_i}}{\frac{1}{a_j}-\frac{1}{a_i}} \\ =& \frac{\frac{b_i-b_j}{b_ib_j}}{\frac{a_i-a_j}{a_ia_j}} \\ =& \frac{a_ia_j(b_i-b_j)}{b_ib_j(a_i-a_j)}\end{array}$
这样就可以避免精度问题。
时间复杂度:$\Theta(n\log n)$($\log$来自排序)。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
struct rec{int a,b,id;}e[300001];
int n;
bool vis[300001],ans[300001];
int sta[300001];
bool cmp(rec a,rec b){return a.a>b.a||(a.a==b.a&&a.b>b.b);}
double slope(rec a,rec b){return 1.0*a.a*b.a*(a.b-b.b)/(1.0*a.b*b.b*(a.a-b.a));}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&e[i].a,&e[i].b);
e[i].id=i;
}
sort(e+1,e+n+1,cmp);
int maxb=e[1].b;
for(int i=2;i<=n;i++)
if(e[i].b<=maxb)vis[i]=1;
else maxb=e[i].b;
sta[++sta[0]]=1;
for(int i=2;i<=n;i++)
{
if(vis[i])continue;
if(slope(e[i],e[sta[sta[0]]])>0)continue;
while(sta[0]>1&&slope(e[i],e[sta[sta[0]]])<slope(e[sta[sta[0]-1]],e[sta[sta[0]]]))sta[0]--;
sta[++sta[0]]=i;
}
for(int i=1;i<=sta[0];i++)
{
ans[e[sta[i]].id]=1;
for(int j=sta[i]+1;j<=n&&e[sta[i]].a==e[j].a&&e[sta[i]].b==e[j].b;j++)ans[e[j].id]=1;
}
for(int i=1;i<=n;i++)if(ans[i])printf("%d ",i);
return 0;
}
rp++
[CSP-S模拟测试]:导弹袭击(数学+凸包+单调栈)的更多相关文章
- [CSP-S模拟测试]:不等式(数学)
题目描述 小$z$热衷于数学.今天数学课的内容是解不等式:$L\leqslant S\times x\leqslant R$.小$z$心想这也太简单了,不禁陷入了深深的思考:假如已知$L,R,S,M$ ...
- [CSP-S模拟测试]:A(数学)
题目传送门(内部题44) 输入格式 一行四个整数,分别表示$S,T,a,b$. 输出格式 输出最小步数,数据保证有解. 样例 样例输入: 10 28 4 2 样例输出: 数据范围与提示 样例解释: 先 ...
- [CSP-S模拟测试]:装饰(数学)
题目传送门(内部题147) 输入格式 每个测试点第一行一个正整数$T$,表示该测试点内的数据组数. 接下来$T$行,每行三个非负整数$a,b,c$,含义如题目中所示. 输出格式 对每组数据输出一行一个 ...
- [CSP-S模拟测试]:最大值(数学+线段树)
题目背景 $Maxtir$最喜欢最大值. 题目传送门(内部题128) 输入格式 第$1$行输入四个正整数$n,m,q$. 第$2$至$n+1$行中,第$i+1$行输入魔法晶石$i$的三种属性$(x_i ...
- [CSP-S模拟测试]:求和(数学)
题目传送门(内部题107) 输入格式 一行五个正整数$x_1,y_1,x_2,y_2,m$ 输出格式 输出一个整数,为所求的答案对$m$取模后的结果. 样例 样例输入: 2 1 5 3 10007 样 ...
- [CSP-S模拟测试]:数列(数学)
题目传送门(内部题95) 输入格式 第一行三个整数$n,a,b$,第二行$n$个整数$x_1\sim x_n$表示数列. 输出格式 一行一个整数表示答案.无解输出$-1$. 样例 样例输入:2 2 3 ...
- [CSP-S模拟测试]:Walker(数学)
题目传送门(内部题86) 输入格式 第一行$n$接下来$n$行,每行四个浮点数,分别表示变换前的坐标和变换后的坐标 输出格式 第一行浮点数$\theta$以弧度制表示第二行浮点数$scale$第三行两 ...
- [CSP-S模拟测试]:Six(数学)
题目传送门(内部题85) 输入格式 一个正整数$N$. 输出格式 一个数表示答案对$1000000007$取模后的结果 样例 样例输入1: 样例输出1: 样例输入2: 样例输出2: 样例输入3: 样例 ...
- [CSP-S模拟测试]:Smooth(数学)
题目传送门(内部题84) 输入格式 两个整数$B,K$ 输出格式 一个整数表示答案 样例 样例输入: 5 100 样例输出: 数据范围与提示 对于$40\%$的数据,保证答案小于$10^7$对于另$2 ...
随机推荐
- MySQL-快速入门(14)MySQL性能优化
1.MySQL性能优化包括查询速度优化.数据库结构优化.数据库服务器优化等. 优化的切入点:合理的结构设计.表结构.索引.查询语句. 2.show status查询数据库的性能参数 show stat ...
- 洛谷 P1631 序列合并(优先队列)
传送门 解题思路 首先读入a.b数组后,sort一遍(从小到大),然后把a[1]+b[1],a[2]+b[1],a[3]+b[1]……a[n]+b[1]全部加入一个优先队列q(小根堆). 然后从一到n ...
- CSRF Failed: CSRF token missing or incorrect
Django设置本身没有关闭CSRF Django设置已经关闭CSRF,可能是由于两个项目都使用同一个端口,调试的时候就会出现Cookie里面csrftoken重用的问题,清理Cookie就好
- php编译完成后,module追加编译进php
# 如果在编译的时候忘记添加某些模块,可以使用这种办法来重新编译添加! # 首先,进入PHP目录(未编译)的扩展目录 cd /home/soft/php-5.2.14/ext/ftp/ # 调用php ...
- PCIeのType0与Type1型配置请求与BAR(基地址寄存器)
PCIe中存在两种配置空间Type0&type1,TYPE0对应非桥设备(Endpoint),Type1对应桥设备(Root和Switch端口中的P2P桥)因为Root每个端口总都含有一个P2 ...
- 【COSMOS】跨链协议IBC概述
一.什么是IBC? IBC是链间通信协议的缩写(Inter-Blockchain Communication Protocol).通过数据包交换在多个不同的区块链网络之间转移数据和状态信息.最初的用途 ...
- STL容器概述
STL容器 1.容器概述 1.1.容器分类 1.1.1.顺序容器:提供对元素序列的访问,顺序容器为元素连续分配内存或将元素组织为链表,元素的类型是容器成员value_type. 顺序容器 说明 vec ...
- 内存分析工具MAT(Memory Analyzer Tool)从安装到使用
一.安装 首先,你得有一个Eclipse(因为MAT是Eclipse的插件) 然后,你要在Eclipse上安装MAT,步骤如下: 1.点击Help,Install New Soft,就出现了以下Ins ...
- mysql使用MRG_MyISAM(MERGE)实现水平分表
在MySQL中数据的优化尤其是大数据量的优化是一门很大的学问,当然其它数据库也是如此,即使你不是DBA,做为一名程序员掌握一些基本的优化信息,也可以让你在自己的程序开发中受益匪浅.当然数据库的优化有很 ...
- python中字典的美化输出
一.背景 如果一个字典长度很大,直接print输出则比较难看,我们需要美化输出,可以借鉴json import json beautiful_format = json.dumps(your_dict ...