第九届河南省ACM省赛 D 导弹发射
来源:互联网 发布:编程求出100以内的质数 编辑:程序博客网 时间:2024/04/28 10:28
D 导弹发射
Description
Alpha 机构研发出一种新型智能导弹,它能够在雷达检测到的区域内,选择一条前进的路径,
击破路径上所有的目标物。
雷达位于(0,0)处,它能够检测到两条射线之间的区域(不妨设在第一象限)。
导弹一开始置放在(0,0)处,它可以在雷达能检测到的区域内先选择一个目标物击破,然后
再继续前进,选择另一个目标物击破。注意,导弹不能沿着这两条射线前进,当然也不能停在原
地。
可以假设,导弹一旦发射,其能量无比大,前进的路径无限长。
已知雷达能够检测到区域,其射线 1:ax-by=0 和射线 2:cx-dy=0。Alpha 机构的总指挥希望
在发现目标群的第一时刻,计算出一条可以击破最多目标物的路径。
Input
第一行: T 表示以下有 T 组测试数据(1≤T ≤8)
对每组测试数据:
第 1 行: n 表示目标物的个数
第 2 行: a b c d 代表两条射线的斜率分别是 a/b 和 c/d。
接下来有 n 行,每行 2 个正整数 xi yi 即第 i 个目标物的坐标。
(1) n<=10^5 0<=a, b, c, d<=10^5 a 和 b 不会同时为 0,c 和 d 不会同时为 0;
(2) 0<= xi , yi <=10^6 i=1,…..,n
Output
每组测试数据,输出占一行,即导弹能击破的最多目标数。
Sample Input
1
15
1 3 2 1
3 1
6 2
4 2
2 5
4 5
6 6
3 4
1 6
2 1
7 4
9 3
5 3
1 3
15 5
12 4
Sample Output
4
解题思路:
首先,我们只需要考虑在曲线之内的点。然后思考,如何判断导弹是前进的?(这个问题在比赛的时候一直困扰我)我们将两条射线看成x轴和y轴进行坐标变换,有了新的坐标后,很容易可以判断前进的情况(x递增,y递增)。变换之后用nlogn的LIS求解即可。这里要注意一个问题,当x轴不变,y轴增大时,LIS有可能将其统计在内。我们在排序时设置,当x相等时y从大到小排序,可以解决上述问题。
这题的题面其实表达的不是很清楚,比如是否有多个目标在同一位置,两条射线的相对位置是否固定。。。然而题目在不考虑这些因素的情况下都能A。。。
代码:
#include <iostream>#include<bits/stdc++.h>using namespace std;const int N=110000;struct node{ double x,y;}a[N],b[N];bool cmp(node a,node b)//先按x从小到大排序,如果x相等按y从大到小排序,这样排除了沿y轴前进的情况{ if(a.x==b.x) return a.y>b.y; return a.x<b.x;}int Search(int num,int low,int high){ int mid; while(low<=high) { mid=(low+high)/2; if(a[num].y>b[mid].y) low=mid+1; else high=mid-1; } return low;}int dp(int n)//LIS nlogn模板{ int i,len,pos; b[1].x=a[1].x; b[1].y=a[1].y; len=1; for(int i=2;i<=n;i++) { //两个点在同一位置的情况,数据中没有 //if(a[i].y>b[len].y&&a[i].x>b[len].x||a[i].x==b[len].x&&a[i].y==b[len].y) if(a[i].y>b[len].y&&a[i].x>b[len].x) { len=len+1; b[len].y=a[i].y; b[len].x=a[i].x; } else { pos=Search(i,1,len); b[pos].y=a[i].y; b[pos].x=a[i].x; } } return len;}int main(){ int T,n; double a1,b1,c1,d1; cin>>T; while(T--) { cin>>n; cin>>a1>>b1>>c1>>d1; //保证c1/d1射线在a1/b1上面,数据中不存在相反情况 /*if(b1==0||c1==0||(b1!=0&&d1!=0&&c1/d1<a1/b1)) { swap(a1,c1); swap(b1,d1); }*/ int cnt=0; for(int i=1;i<=n;i++) { double x,y; scanf("%lf%lf",&x,&y); //如果点在两个射线之内 if(y*d1<x*c1&&x*a1<y*b1) { cnt++; //坐标变换 a[cnt].x=(x-y*d1/c1)*c1/sqrt(c1*c1+d1*d1); a[cnt].y=(y-x*a1/b1)*b1/sqrt(a1*a1+b1*b1); } } sort(a+1,a+cnt+1,cmp); cout<<dp(cnt)<<endl; }}
0 0
- 第九届河南省ACM省赛 D 导弹发射
- 导弹发射-河南省第九届省赛D题
- NYOJ-导弹发射-河南省第九届省赛D题【LIS】
- 机器设备 河南省第九届ACM省赛
- nyoj 1279 (河南省第九届ACM比赛 D 题)
- 第九届河南省ACM题解
- nyoj1276机器设备(河南省第九届ACM省赛)
- NYOJ1277 Decimal integer conversion(模拟)(河南省第九届ACM省赛)
- 河南省第九届ACM赛后总结
- 河南省第九届ACM C题
- 河南省第九届ACM程序设计大赛总结
- 河南省第十届ACM题解 D 年终奖金
- nyoj 1275 导弹发射(河南省2016年省赛)
- 『NYIST』第九届河南省ACM竞赛队伍选拔赛[正式赛二]--Codeforces -35D. Animals
- NYOJ1274 信道安全(最短路,SPFA)(河南省第九届ACM省赛)
- NYOJ1272 表达式求值(后缀求值,特殊处理)(河南省第九届ACM省赛)
- 河南省第九届acm省赛 A:表达式求值 逆波兰表达式
- 2016河南省第九届ACM程序设计竞赛[正式赛四]
- 游乐场 ssl1776 双连通分量
- Redis常用命令
- SpringMVC学习:一、基础概念
- UART基础知识
- GM、VP、FVP、CIO都是什么职位?
- 第九届河南省ACM省赛 D 导弹发射
- 对象的常指针和常引用
- Golang 单元测试和性能测试
- 最详细的Log4j使用教程
- Linux操作系统学习_3
- 51nod1381
- Python模块环境搭建 -- ubuntu
- Codeforces Round #405 Bear and Friendship Condition 并查集
- Tarjan算法详解