按斜率排序,斜率线相同的直线取截距最大的
一条直线能够被看到的条件是,与比它斜率小的交点在比它斜率大的交点的左侧
1007: [HNOI2008]水平可见直线
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 4234 Solved: 1558
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,Bi
Output
从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必须有个空格
Sample Input
3
-1 0
1 0
0 0
Sample Output
1 2
HINT
C++:
/* *********************************************** Author :CKboss Created Time :2015年05月10日 星期日 08时38分36秒 File Name :BZOJ1007.cpp ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <cstdlib> #include <vector> #include <queue> #include <set> #include <map> using namespace std; const int maxn=50500; int n; struct Line { int id; int k,b; }line[maxn]; bool cmp(Line A,Line B) { if(A.k!=B.k) return A.k<B.k; return A.b>B.b; } Line stack[maxn]; int st; double cal(Line X,Line Y) /// Line X < Line Y { return (double)(Y.b-X.b)/(X.k-Y.k); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%d",&n); for(int i=0;i<n;i++) { int x,y; scanf("%d%d",&x,&y); line[i]=(Line){i+1,x,y}; } sort(line,line+n,cmp); int m=0; int lastk=8888888; for(int i=0;i<n;i++) { if(lastk!=line[i].k) { line[m++]=line[i]; lastk=line[i].k; } } n=m; stack[st++]=line[0]; for(int i=1;i<n;i++) { while(st>1&&cal(stack[st-2],stack[st-1])>=cal(stack[st-1],line[i])) st--; stack[st++]=line[i]; } vector<int> v; for(int i=0;i<st;i++) v.push_back(stack[i].id); sort(v.begin(),v.end()); for(int i=0;i<st;i++) printf("%d ",v[i]); putchar(10); return 0; }
JAVA:
import java.util.*; public class Main { final int maxn=50500; final double eps = 1e-7; int n; public class Line{ public int k,b,id; } public class cmp1 implements Comparator{ public int compare(Object x,Object y){ Line A=(Line)x,B=(Line)y; if(A.k!=B.k) return A.k-B.k; return B.b-A.b; } } Line[] line=new Line[maxn]; double CAL(Line A,Line B){ return (double)(B.b-A.b)/(A.k-B.k); } Line[] Stack=new Line[maxn]; int st; public Main() { Scanner in = new Scanner(System.in); n=in.nextInt(); for(int i=0;i<n;i++){ line[i]=new Line(); line[i].k=in.nextInt(); line[i].b=in.nextInt(); line[i].id=i+1; } Arrays.sort(line,0,n,new cmp1()); int last=888888; int m=0; for(int i=0;i<n;i++){ if(line[i].k!=last){ line[m++]=line[i]; last=line[i].k; } } n=m; Stack[0]=line[0]; st=1; for(int i=1;i<n;i++){ while(st>1&&CAL(Stack[st-1],Stack[st-2])>=CAL(Stack[st-1],line[i])) st--; Stack[st++]=line[i]; } Vector vi=new Vector<Integer>(); for(int i=0;i<st;i++){ vi.add(Stack[i].id); } Collections.sort(vi); for(int i=0;i<st;i++){ System.out.printf("%d ",vi.get(i)); } } public static void main(String[] args){ new Main(); } }
时间: 2024-10-09 21:51:53