HDU_Steps7.1 几何入门 HDU2108 HDU1886 HDU1115 HDU1392 HDU1577 HDU1147 HDU2215 HDU2202

 

7.1.1 HDU2108 Shape of HDU

判断凸多边形,每连续三个点之间求叉积判断即可

7.1.2 HDU1086 You can Solve a Geometry Problem too

判断线段相交,模板题,参考吉大模板

7.1.3 HDU1115 Lifting the Stone

多边形重心,模板题,参考吉大模板

7.1.4 HDU1392 Surround the Trees

凸包,计算周长

 

#include <cstdio>
#include <string>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct point{
	double x,y;
}pnt[110],res[110];
int n,ind;
//小于0,说明P0P1>P0P2(极角) 
double mult(point p0,point p1,point p2){
	return (p2.y-p0.y)*(p1.x-p0.x)-(p1.y-p0.y)*(p2.x-p0.x);	
}
double dis(point px,point py){
	return sqrt((py.y-px.y)*(py.y-px.y)+(py.x-px.x)*(py.x-px.x));
}
bool cmp(const point &a,const point &b){
	double t=mult(pnt[0],a,b);
	if(t!=0)return t>0;
	return dis(pnt[0],a)<dis(pnt[0],b); 
}
double graham(){
	//当点数不多于3个的时候,直接返回答案 
	if(n==1)return 0;
	if(n==2)return dis(pnt[0],pnt[1]);
	if(n==3)return dis(pnt[0],pnt[1])+dis(pnt[1],pnt[2])+dis(pnt[2],pnt[0]);
	//寻找y坐标最小的点(y坐标相同取x最小) 
	ind=0;
	for(int i=1;i<n;i++){
		if(pnt[i].y<pnt[ind].y||pnt[i].y==pnt[ind].y&&pnt[i].x<pnt[ind].x)ind=i;	
	}
	if(ind!=0){
		point tmp=pnt[0];
		pnt[0]=pnt[ind];
		pnt[ind]=tmp;	
	}
	//按照极角从小到大排序,相同时按照距离第一个点距离排序 
	sort(pnt+1,pnt+n,cmp);
	//加点 
	int top=1;
	res[0]=pnt[0],res[1]=pnt[1];
	for(int i=2;i<n;i++){
		while(mult(res[top-1],res[top],pnt[i])<0)top--;
		res[++top]=pnt[i];	
	}
	//计算周长 
	double r=dis(res[0],res[top]);
	for(int i=1;i<=top;i++){
		r+=dis(res[i],res[i-1]);
	}
	
	return r;
}
int main(){
	while(scanf("%d",&n),n){ 
		for(int i=0;i<n;i++)scanf("%lf%lf",&pnt[i].x,&pnt[i].y);
    	
		printf("%.2lf\n",graham());
	} 
    return 0;
}


 

7.1.5 HDU1577 WisKey的眼神

当直角三角形两直角边互质时,斜边不会经过其它整点(通过相似三角形可以证明)

gcd(fabs(sx-px),fabs(sy-py))==1?"Yes\n":"No\n"

7.1.6 HDU1147 Pick-up sticks

o(n^2)的枚举,理论超时却能过这题,数据弱?还是break的作用使实际复杂度低于O(n^2)?

#include <cstdio>
#include <algorithm>
#define INF 1e20
#define eps 1e-10
#define MAXN 100010
using namespace std;
struct point{double x,y;};
struct line{point a,b;int top;}l[MAXN];
int n;
double xmult(point p1,point p2,point p0){
	return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);	
}
int cross(line u,line v){
	return ((max(u.a.x,u.b.x)>=min(v.a.x,v.b.x))&& 
			(max(v.a.x,v.b.x)>=min(u.a.x,u.b.x))&& 
			(max(u.a.y,u.b.y)>=min(v.a.y,v.b.y))&& 
			(max(v.a.y,v.b.y)>=min(u.a.y,u.b.y))&& 
			(xmult(v.a,u.b,u.a)*xmult(u.b,v.b,u.a)>=0)&&
			(xmult(u.a,v.b,v.a)*xmult(v.b,u.b,v.a)>=0));
}
int main(){
	while(scanf("%d",&n),n){
		for(int i=0;i<n;i++){
			scanf("%lf%lf%lf%lf",&l[i].a.x,&l[i].a.y,&l[i].b.x,&l[i].b.y);	
		}
		for(int i=0;i<n;i++){
			int yes=1;
			l[i].top=0;
			for(int j=i+1;j<n;j++){
				if(cross(l[i],l[j])){yes=0;break;}
			}	
			if(yes)l[i].top=1;
		}
		
		printf("Top sticks: ");
		int ind=0;
		for(;ind<n;ind++)if(l[ind].top==1){printf("%d",ind+1);break;}
		for(ind++;ind<n;ind++)if(l[ind].top==1){printf(", %d",ind+1);}
		printf(".\n");
	}
	return 0;	
}


 

7.1.7 HDU2215 Maple trees

求最大外接圆,先求出凸包上的点,再每次枚举三个点,当钝角三角形时,r=最大边/2,否则r=c/(2sin(a,b))=a*b*c/(2(axb)).求出最大R即可

7.1.8 HDU2202 最大三角形

模板凸包,然后枚举凸包上的三点即可求叉积即可

你可能感兴趣的:(HDU_Steps7.1 几何入门 HDU2108 HDU1886 HDU1115 HDU1392 HDU1577 HDU1147 HDU2215 HDU2202)