bzoj1007【hnoi2008】水平可见直线
2015-08-17 20:25
429 查看
1007: [HNOI2008]水平可见直线
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4537 Solved: 1669
[Submit][Status][Discuss]
Description
在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.例如,对于直线:
L1:y=x; L2:y=-x; L3:y=0
则L1和L2是可见的,L3是被覆盖的.
给出n条直线,表示成y=Ax+B的形式(|A|,|B|<=500000),且n条直线两两不重合.求出所有可见的直线.
Input
第一行为N(0 < N < 50000),接下来的N行输入Ai,BiOutput
从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必须有个空格Sample Input
3-1 0
1 0
0 0
Sample Output
1 2计算几何
本体做法比较直观,先按斜率从小到大排序,再将斜率最小的两条直线如栈。对于每条直线,如果其与栈顶直线的交点在上一个点的左边,就将栈顶直线出栈。方法正确性很好证明,因大家自行脑补。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define MAXN 50001 #define F(i,j,k) for(int i=j;i<=k;i++) #define D(i,j,k) for(int i=j;i>=k;i--) #define eps 1e-8 using namespace std; struct Data { double a,b; int num; }l[MAXN],s[MAXN]; int n,top=0,ans[MAXN]; bool cmp(Data x,Data y) { if (fabs(x.a-y.a)<eps) return x.b<y.b; else return x.a<y.a; } double cross_x(Data x,Data y) { return (x.b-y.b)/(y.a-x.a); } int main() { scanf("%d",&n); F(i,1,n) { scanf("%lf%lf",&l[i].a,&l[i].b); l[i].num=i; } sort(l+1,l+n+1,cmp); F(i,1,n) { while (top) { if (fabs(s[top].a-l[i].a)<eps) top--; else if (top>1&&cross_x(s[top-1],l[i])<=cross_x(s[top-1],s[top])) top--; else break; } s[++top]=l[i]; } memset(ans,0,sizeof(ans)); F(i,1,top) ans[s[i].num]=1; F(i,1,n) if (ans[i]) printf("%d ",i); printf("\n"); }
相关文章推荐
- GDOI模拟 蜘蛛侠
- oracle里面的时间转字符串to_char(),字符串转时间to_date(),以及substr和instr的使用。
- TweenMax参数补充
- underscore chain
- 2014ACM/ICPC亚洲区广州站 Song Jiang's rank list
- 机房收费系统之子窗体显示
- 浏览器缓存详解:expires,cache-control,last-modified,etag详细说明
- 查看Linux进程CPU过高具体的线程堆栈(不中断程序)
- reverse bits
- 【bzoj2150】 部落战争 二分图匹配
- POJ 2001 Shortest Prefixes
- hdu3068最长回文(manacher算法)
- Android:The connection to adb is down, and a severe error has occured错误解决
- 从Mysql转到Oracle前需了解的50件事
- HDU 3788 和九度OJ 1006测试数据是不一样的
- (C++ 11) 泛型算法(一)
- Intel VT-x enabled 却无法打开64位虚拟机
- Android文件上传,PHP端接收
- BFS-HDU-1495-非常可乐
- 软件测试之独步武林系列(一)