判断线段相交
struct point{
double x,y;
};
struct line{
point p1,p2;
}a[100010];
//叉乘
double chacheng(point p1,point p2,point p3){
return (p1.x-p3.x)*(p2.y-p3.y)-(p1.y-p3.y)*(p2.x-p3.x);
}
//判断是否相交
int judge(line l1,line l2){
if( min(l2.p1.x,l2.p2.x)<=max(l1.p1.x,l1.p2.x)
&& min(l2.p1.y,l2.p2.y)<=max(l1.p1.y,l1.p2.y)
&& min(l1.p1.x,l1.p2.x)<=max(l2.p1.x,l2.p2.x)
&& min(l1.p1.y,l1.p2.y)<=max(l2.p1.y,l2.p2.y)
&& chacheng(l1.p1,l2.p2,l2.p1)*chacheng(l1.p2,l2.p2,l2.p1)<=0
&& chacheng(l2.p1,l1.p2,l1.p1)*chacheng(l2.p2,l1.p2,l1.p1)<=0 )
return 1;
else
return 0;
}
Pick-up sticks
题意
Stan有n根不同长度的棍子。他一次一根地将棍子随机地扔在地板上,然后,Stan试图找到在最上面的棍子,也就是没有其他的棍子压在这样的棍子上面。Stan已经注意到,最后扔出的棍子总在最上面,但他想知道所有在最上面的棍子。Stan的棍子非常地薄,其厚度可以忽略不计(如图,表示第一个样例的输入输出)。
输入
输入由若干测试用例组成。每个测试用例首先给出1≤n≤100000,表示这一测试用例中棍子的个数;接下来的n行每行给出4个数,这些数是一根棍子的端点的平面坐标,棍子列表的顺序是按Stan扔棍子的顺序。本题设定在最上面的棍子不超过1000根。输入以n=0结束,程序不用处理这一测试用例。
输出
对每个测试用例,输出一行,给出在最上面的棍子的列表,格式按样例。在最上面的棍子的列表顺序按Stan扔棍子的顺序。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define ll long long
int flag[100010];
struct point{
double x,y;
};
struct line{
point p1,p2;
}a[100010];
//叉乘
double chacheng(point p1,point p2,point p3){
return (p1.x-p3.x)*(p2.y-p3.y)-(p1.y-p3.y)*(p2.x-p3.x);
}
//判断是否相交
int judge(line l1,line l2){
if( min(l2.p1.x,l2.p2.x)<=max(l1.p1.x,l1.p2.x)
&& min(l2.p1.y,l2.p2.y)<=max(l1.p1.y,l1.p2.y)
&& min(l1.p1.x,l1.p2.x)<=max(l2.p1.x,l2.p2.x)
&& min(l1.p1.y,l1.p2.y)<=max(l2.p1.y,l2.p2.y)
&& chacheng(l1.p1,l2.p2,l2.p1)*chacheng(l1.p2,l2.p2,l2.p1)<=0
&& chacheng(l2.p1,l1.p2,l1.p1)*chacheng(l2.p2,l1.p2,l1.p1)<=0 )
return 1;
else
return 0;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
if(n==0) break;
for(int i=0;i<n;i++)
scanf("%lf %lf %lf %lf",&a[i].p1.x,&a[i].p1.y,&a[i].p2.x,&a[i].p2.y);
memset(flag,0,sizeof(flag));
for(int i=0; i<n-1; i++)
for(int j=i+1; j<n; j++)
if(judge(a[i],a[j]))
{
flag[i]=1;
break;
}
printf("Top sticks: ");
for(int i=0; i<n; i++)
if(flag[i]==0)
{
if(i==n-1)
printf("%d.\n",i+1);
else
printf("%d, ",i+1);
}
}
return 0;
}