题目链接:http://poj.org/problem?id=2653
——————————————————————————————————————
题目描述: 按顺序增加线段,后增加的若与前面的相交,则后面的在前面的上方。问处于最上方(谁都没压着它)的线段有哪些
——————————————————————————————————————
题目思路:
用了两个队列,一遍ac,简单的几何。
—————————————————————————————————————
#include <cstdio>
#include <iostream>
#include <cstring>
#include <math.h>
#include <queue>
using namespace std;
#define INF 10000000000
#define min(a,b) ((a)>(b)?(b):(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define maxn 110
const double eps = 1e-10;
typedef double T;
int n = 0;
struct Pt
{
T x;
T y;
Pt(){}
Pt(T px,T py) { x = px; y = py; }
Pt operator +(const Pt &p) { return Pt(x+p.x,y+p.y); }
Pt operator -(const Pt &p) { return Pt(x-p.x,y-p.y); }
int operator ==(const Pt &p)
{
T temp = 0;
temp = sqrt((x - p.x)*(x - p.x)+(y-p.y)*(y-p.y));
if(temp<eps)
return 1;
else
return 0;
}
};
struct Line
{
Pt a;
Pt b;
int num;
Line(){}
Line (Pt p1,Pt p2) { a = p1; b = p2;}
};
//ab * cd
T dpr(Pt a,Pt b,Pt c,Pt d) { return (b.x-a.x)*(d.x-c.x)+(b.y-a.y)*(d.y-c.y);}
T dpr_three(Pt a,Pt b,Pt c) { return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);}
//ab × cd
T cpr(Pt a,Pt b,Pt c,Pt d){ return (b.x-a.x)*(d.y-c.y)-(b.y-a.y)*(d.x-c.x);}
T cpr_three(Pt a,Pt b,Pt c) { return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);}
T det(const Pt& a,const Pt& b) { return a.x*b.y - a.y*b.x; }
T dot(const Pt& a,const Pt& b) { return a.x*b.x + a.y*b.y; }
//-------------符号函数--------------------
int sgn(T x) { return x<-eps?-1:x>eps;}
int epsfun(T x)
{
if(x<-eps || x<eps)
return 0;
else
return x;
}
bool cmp(Line l1,Line l2) { return l1.a.x < l2.a.x; }
T d(Pt a,Pt b) { return sqrt((a.x - b.x)*(a.x - b.x) + (a.y-b.y)*(a.y - b.y));}
void judge_line(Line line1 ,Line line2) //判断两直线位置关系并求交点
{
if(sgn(cpr(line1.b,line1.a,line2.b,line2.a) == 0))
{
if(sgn(cpr(line1.b,line1.a,line2.b,line1.a) == 0))
printf("LINE\n");
else
printf("NONE\n");
}
else
{
T s1 = cpr(line1.b,line1.a,line2.a,line1.a),s2 = cpr(line1.b,line1.a,line2.b,line1.a);
printf("POINT ");
printf("%.2f %.2f\n",(line2.a.x*s2-line2.b.x*s1)/(s2-s1),(line2.a.y*s2-line2.b.y*s1)/(s2-s1));
}
}
//-------------直线线段相交--------------------
//直线与线段 规范相交: Line a为直线,Line b为线段
int line_seg_cross(Line a,Line b)
{
if(sgn(cpr(a.b,a.a,b.a,a.a))*sgn(cpr(a.b,a.a,b.b,a.a))<0)
return 1;
else
return 0;
}
int res_line_seg_cross()
{
}
//-------------线段线段相交--------------------
int between(Pt a,Pt b,Pt c)
{
if(dpr_three(a,c,b)<0)
return 1;
return 0;
}
//非规范相交(包括多个交点)
int segcross(Pt a,Pt b,Pt c,Pt d)
{
T s1 = 0,s2 = 0,s3 = 0,s4 = 0;
int d1 = 0,d2 = 0,d3 = 0,d4 = 0 ;
d1 = sgn(s1 = cpr_three(a,b,c));
d2 = sgn(s2 = cpr_three(a,b,d));
d3 = sgn(s3 = cpr_three(c,d,a));
d4 = sgn(s4 = cpr_three(c,d,b));
if((d1^d2) == -2 && (d3^d4) == -2) return 1;
if((d1 == 0 && between(c,a,b)) || (d2 == 0 && between(d,a,b)) || (d3 == 0 && between(a,c,d)) || (d4 == 0 && between(b,c,d)))
return 1;
return 0;
}
//判规范相交
bool res_segcross(Line a,Line b)
{
int d1 = sgn(det(a.a-b.a,b.b-b.a)),
d2 = sgn(det(a.b-b.a,b.b-b.a)),
d3 = sgn(det(b.a-a.a,a.b-a.a)),
d4 = sgn(det(b.b-a.a,a.b-a.a));
if (d1*d2 == -1 && d3*d4 == -1)
return true;
return false;
}
//规范相交:1, 非规范相交且交点有无数个:3 非规范相交且交点唯一:2 不相交:0
int segcross_all(Pt a,Pt b,Pt c,Pt d,Pt *p) //规范相交:1, 非规范相交且交点有无数个:3 非规范相交且交点唯一:2 不相交:0
{
T s1 = 0,s2 = 0,s3 = 0,s4 = 0;
int d1 = 0,d2 = 0,d3 = 0,d4 = 0 ;
d1 = sgn(s1 = cpr_three(a,b,c));
d2 = sgn(s2 = cpr_three(a,b,d));
d3 = sgn(s3 = cpr_three(c,d,a));
d4 = sgn(s4 = cpr_three(c,d,b));
if((d1^d2) == -2 && (d3^d4) == -2)
{
(*p).x = (c.x*s2 - d.x*s1)/(s2 - s1);
(*p).y = (c.y*s2 - d.y*s1)/(s2 - s1);
return 1;
}
if(d1 || d2 || d3 ||d4)
return 3;
if(d1 == 0 && between(c,a,b))
{
(*p).x = c.x;
(*p).y = c.y;
return 2;
}
if(d2 == 0 && between(d,a,b))
{
(*p).x = d.x;
(*p).y = d.y;
return 2;
}
if(d3 == 0 && between(a,c,d))
{
(*p).x = a.x;
(*p).y = a.y;
return 2;
}
if(d4 == 0 && between(b,c,d))
{
(*p).x = b.x;
(*p).y = b.y;
return 2;
}
return 0;
}
queue<Line>qline[2];
int main()
{
//freopen("in.in", "r", stdin);
//freopen("out.txt","w",stdout);
int n = 0,i = 0;
T x1 = 0,y1 = 0,x2,y2;
int cur = 0;
while(scanf("%d",&n) && n)
{
cur = 1;
while(!qline[0].empty())qline[0].pop();
while(!qline[1].empty())qline[1].pop();
for(i = 0;i<n;i++)
{
Line line;
int next = (cur? 0:1);
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
line = Line(Pt(x1,y1),Pt(x2,y2));
line.num = i;
while(!qline[cur].empty())
{
Line temp = qline[cur].front();
qline[cur].pop();
if(!(res_segcross(line,temp)==1))
qline[next].push(temp);
}
qline[next].push(line);
cur = cur?0:1;
}
printf("Top sticks:");
int flag = 0;
while(!qline[cur].empty())
{
if(flag == 0)
printf(" %d",qline[cur].front().num+1),flag = 1;
else
printf(", %d",qline[cur].front().num+1);
qline[cur].pop();
}
printf(".\n");
}
return 0;
}