您的位置:首页 > 其它

FOJ 2148 给定的二维坐标 能构成的凸四边形数

2013-12-22 20:46 369 查看
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2148

题意:

求给定的二维坐标能构成的凸四边形数

思路:

我们可以得到一个结论:

当且仅当四边形为凸四边形时,对角线能相交 -> 若四边形存在线段相交就是凸四边形



#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
#define ST 1001   
#define EN 1002   
#define M 10000   
#define inf 1000000   
#define eps 1e-8   
#define PR 1e-8
struct Point{//点是2维的   
    double x,y;  
}p[50];  
struct v{  
    Point Start,End;  
};  
  
double Cross(Point p1,Point p2,Point p3,Point p4){//二维向量(p1p2)X(p3p4) 返回第三向量长度   
    double x1=p2.x-p1.x,y1=p2.y-p1.y;  
    double x2=p4.x-p3.x,y2=p4.y-p3.y;  
    return x1*y2-x2*y1; //为0表示 p1p2 与p3p4共线   
    //直线:不为0就是相交   
}    
double Cross_v(v v1,v v2){  
    return Cross(v1.Start,v1.End,v2.Start,v2.End);  
}  
double point_dis(Point p1,Point p2){  
    return sqrt((double)((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));  
}  
bool On_Segment(Point p1,Point p2,Point p3){//p3点在 p1p2线段上   
    if(Cross(p1,p2,p1,p3)!=0)return false;  
    bool iny=(p1.y<=p3.y && p3.y<=p2.y)||(p1.y>=p3.y && p3.y>=p2.y);  
    bool inx=(p1.x<=p3.x && p3.x<=p2.x)||(p1.x>=p3.x && p3.x>=p2.x);  
    if(inx && iny)return true;  
    return false;  
}  
bool Segmentintersect(Point p1,Point p2,Point p3,Point p4){//p1p2 是否与 p3p4相交   
    double cross_1=Cross(p3,p4,p3,p1),cross_2=Cross(p3,p4,p3,p2);//cross_1 2必须一正一负且都不为0   
    double cross_3=Cross(p1,p2,p1,p3),cross_4=Cross(p1,p2,p1,p4);//cross_2 4必须一正一负且都不为0   
    //表示a线段 2点 在b线段 2侧   
    if(cross_1*cross_2<0 && cross_3*cross_4<0)return true;  
  
    //a线段端点在 b线段上 视情况取舍这种位置    
//  if(cross_1==0 && On_Segment(p3,p4,p1))return true;   
//  if(cross_2==0 && On_Segment(p3,p4,p2))return true;   
//  if(cross_3==0 && On_Segment(p1,p2,p3))return true;   
//  if(cross_4==0 && On_Segment(p1,p2,p4))return true;   
    return false;  
}  
int ok(Point a,Point b, Point c,Point d){
	bool ans = Segmentintersect(a,b,c,d) ;
	ans|= Segmentintersect(a,c,b,d) ;
	ans|= Segmentintersect(a,d,c,b) ;
	return ans;
}

int main()
{
	int T,Cas = 1;
	scanf("%d",&T);
	int i, j, k, l;
	while(T--){
		int n, ans=0;scanf("%d",&n);
		for(i=0;i<n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
		for(i = 0; i < n; i++)
			for(j = i+1; j <n; j++)
				for(k = j+1;k<n;k++)
					for(l = k+1;l<n;l++)
						ans += ok(p[i],p[j],p[k],p[l]);

		printf("Case %d: %d\n",Cas++,ans);		
	}
	return 0;
}
/*
99
4
0 0
100 0
0 100
100 100
4
0 0
100 0
0 100
10 10

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐