POJ 计算几何专项训练(2) 【1269】&【1410】&【1696】&【3347】&【2826】

POJ 1269 Intersecting Lines

题意很简单、判断两条直线是重合平行还是相交、如果相交输出交点、

Code:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>

#define EPS 1e-9
#define INF 1e10

using namespace std;

int vv;
double x1,x2,x3,x4,yy1,y2,y3,y4;

bool eq(double x1,double x2){
	return	abs(x1-x2)<EPS;
}

double slope(double x1,double y1,double x2,double y2){
	if	(eq(x1,x2))		return	INF;
	return	(y2-y1)/(x2-x1);
}

int main(){
	printf("INTERSECTING LINES OUTPUT\n");
	scanf("%d",&vv);
	while	(vv--){
		scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&yy1,&x2,&y2,&x3,&y3,&x4,&y4);
		double k1=slope(x1,yy1,x2,y2),k2=slope(x3,y3,x4,y4);
		if	(eq(k1,k2))
			if	((eq(x1,x2) && eq(x1,x3)) || (eq(yy1-k1*x1,y3-k2*x3)))
				printf("LINE\n");
			else	printf("NONE\n");
		else{
			double b1=yy1-x1*k1,b2=y3-k2*x3;
			printf("POINT %.2lf %.2lf\n",(b2-b1)/(k1-k2),k1*(b2-b1)/(k1-k2)+b1);
		}	
	}
	printf("END OF OUTPUT\n");
	return	0;
}

  

POJ 1410 Intersection

判断一条直线和一个矩形是否有公共部分(包含也算)、

Code:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>

#define EPS 1e-9
#define INF 1e10

using namespace std;

struct segment{
	double beginx,beginy,endx,endy;
};

double crossp(double x1,double y1,double x2,double y2){
	return x1*y2-x2*y1;
}

int cross(segment a,segment b){
	if	(min(a.beginx,a.endx)>max(b.beginx,b.endx) ||\
	     min(b.beginx,b.endx)>max(a.beginx,a.endx) ||\
		 min(a.beginy,a.endy)>max(b.beginy,b.endy) ||\
		 min(b.beginy,b.endy)>max(a.beginy,a.endy))	return	0;
	if	(crossp(a.beginx-b.beginx,a.beginy-b.beginy,b.endx-b.beginx,b.endy-b.beginy)\
		*crossp(b.endx-b.beginx,b.endy-b.beginy,a.endx-b.beginx,a.endy-b.beginy)>=0 &&\
		 crossp(b.beginx-a.beginx,b.beginy-a.beginy,a.endx-a.beginx,a.endy-a.beginy)\
		*crossp(a.endx-a.beginx,a.endy-a.beginy,b.endx-a.beginx,b.endy-a.beginy)>=00)	return	1;
	return	0;
}

int vv;
segment temp,p;
double lx,rx,ty,by;

int main(){
	scanf("%d",&vv);
	while	(vv--){
		scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&temp.beginx,&temp.beginy,&temp.endx,&temp.endy,&lx,&ty,&rx,&by);
		if	(lx>rx)	swap(lx,rx);
		if	(by>ty)	swap(by,ty);
		if	(temp.beginx>=lx && temp.beginx<=rx && temp.beginy>=by && temp.beginy<=ty &&\
			 temp.endx>=lx && temp.endx<=rx && temp.endy>=by && temp.endy<=ty){
			 	cout <<'T' <<endl;
			 	continue;
			 }
		p.beginx=p.endx=lx;p.beginy=by;p.endy=ty;
		if	(cross(temp,p)){
			cout <<'T' <<endl;
			continue;
		}
		p.beginx=p.endx=rx;
		if	(cross(temp,p)){
			cout <<'T' <<endl;
			continue;
		}
		p.beginx=lx;p.endx=rx;p.beginy=p.endy=by;
		if	(cross(temp,p)){
			cout <<'T' <<endl;
			continue;
		}
		p.beginy=p.endy=ty;
		if	(cross(temp,p)){
			cout <<'T' <<endl;
			continue;
		}
		else	cout <<'F' <<endl;
	}
	return	0;
}

  

POJ 1696 Space Ant

卷包裹的概念题、

Code:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>

#define INF 1e9

using namespace std;

struct point{
	int x,y;
};

inline int distsquare(point A,point B){return (B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y);}
inline int det(int x1,int y1,int x2,int y2){return x1*y2-x2*y1;}
inline int cross(point A,point B,point C,point D){return det(B.x-A.x , B.y-A.y , D.x-C.x , D.y-C.y);}

int vv,n;

int main(){
	scanf("%d",&vv);
	while(vv--){
		scanf("%d",&n);
		point* node=new point[n+1];
		int* conbag=new int[n+1];
		bool* vist=new bool[n+1];
		int min_y=INF,fi=0;
		for(int i=1;i<=n;i++){
			int num;
			cin>>num>>node[i].x>>node[i].y;
			vist[i]=false;
			if(min_y > node[i].y){
				min_y = node[i].y;
				fi=i;
			}
		}
		conbag[1]=fi;conbag[0]=1;vist[fi]=true;
		int pc=1;   
		while(1){
			int s=conbag[pc];  
			int k;    
			for(int i=1;i<=n;i++) 
				if(!vist[i]){
					k=i;
					break;
				}
			for(int i=1;i<=n;i++)
				if(i!=k && !vist[i]){
					int temp=cross(node[s],node[k],node[s],node[i]);
					if(temp<0)	k=i;
					else
						if(temp==0)
							if(distsquare(node[s],node[k]) > distsquare(node[s],node[i]))	k=i;
				}
			conbag[++pc]=k;conbag[0]++;vist[k]=true;
			if(n-conbag[0]==1)	break;
		}
		printf("%d ",conbag[0]+1);
		fi=0;
		for(int i=1;i<=conbag[0];i++){
			printf("%d ",conbag[i]);
			if(!vist[i])	fi=i;
		}
		if (fi)	cout<<fi<<endl;
		else	cout<<n<<endl;
		delete node;delete conbag;delete vist;
	}
	return 0;
}

  

POJ 3347 Kadj Squares

这个题目很有意思、、

首先,因为无论怎么扩大或者缩小边长,只要是同时对所有图形处理,都不会有问题、于是小数问题被解决了、

其次、对于每个正方形,如果它比前面一个小,显然放在那个的“下面”,否则,情况就比较复杂、于是我为乐简化讨论、对前面所有正方形求一下它能摆的最左位置,然后找出其中的最大值、

最后刷一个高度数组来判断可见、

Code:

#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>

#define sign printf("*\n")

using namespace std;

int h[5001],v[5001],len[5001],p[5001],fr[5001];
int n;

int main(){
	scanf("%d",&n);
	while	(n){
		memset(fr,0,sizeof fr);
		for	(int i=1;i<=n;i++){
			scanf("%d",&len[i]);
			len[i]*=4;
		}
		p[1]=0;
		for	(int i=2;i<=n;i++)
			if	(len[i]<len[i-1])	p[i]=p[i-1]+len[i-1]+len[i];
			else{
				int cur=0;
				for	(int j=1;j<i;j++)
					if	(len[j]>len[i])	cur=max(cur,p[j]+len[j]+len[i]);
					else	cur=max(cur,p[j]+len[j]*3-len[i]);
				p[i]=cur;
			}
		//sign;
		memset(h,0,sizeof h);
		for	(int i=1;i<=n;i++){
			int cur=len[i];
			for	(int j=0;j<len[i];j++){
				if	(cur>h[p[i]+j]){
					h[p[i]+j]=cur;
					fr[p[i]+j]=i;
				}
				cur++;
			}
			if	(cur>h[p[i]+len[i]]){
				h[p[i]+len[i]]=cur;
				fr[p[i]+len[i]]=i;
			}
			for	(int j=len[i]+1;j<=len[i]*2;j++){
				cur--;
				if	(cur>h[p[i]+j]){
					h[p[i]+j]=cur;
					fr[p[i]+j]=i;
				}
			}
		}
		//for	(int i=1;i<=n;i++)	printf("%d %d\n",i,p[i]);
		memset(v,0,sizeof v);
		for	(int i=0;i<=5000;i++)
			v[fr[i]]++;
		int c=0;
		for	(int i=1;i<=n;i++)
			if	(v[i]){
				if	(!c)	c++;else printf(" ");
				printf("%d",i);
			}
		printf("\n");
		scanf("%d",&n);
	}
}

  

POJ 2826 An Easy Problem?!

太恶心了!、

题意很好理解,然后有以下几种特殊情况:

有水平线;

开口不是朝上的;

两条线段没有交点;

两条线段重合、

以上判断方法都不难、都考虑到就可以了、

(本题实际上是不卡精度的、列方程求解也可过、

Code:

#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>

#define EPS 1e-20
#define sqr(x) ((x)*(x))
#define INF 1e9
#define sign printf("*\n")

using namespace std;

struct	segment{
	double sx,sy,ex,ey;	
};

segment s1,s2;

int eq(double xx,double yy){
	return abs(xx-yy)<EPS;
}


double dis(double x1,double y1,double x2,double y2){
	return sqrt(sqr(x1-x2)+sqr(y1-y2));
}

double crossp(double x1,double y1,double x2,double y2){
	return x1*y2-x2*y1;
}

double slope(double x1,double y1,double x2,double y2){
	return	(eq(x1,x2)?INF:(y2-y1)/(x2-x1));
}

int cross(segment a,segment b){
	if	(max(a.sx,a.ex)<min(b.sx,b.ex) || max(a.sy,a.ey)<min(b.sy,b.ey) \
	||   min(a.sx,a.ex)>max(b.sx,b.ex) || min(a.sy,a.ey)>max(b.sy,b.ey))	return	0;
	if	(crossp(a.sx-b.sx,a.sy-b.sy,b.ex-b.sx,b.ey-b.sy)*crossp(b.ex-b.sx,b.ey-b.sy,a.ex-b.sx,a.ey-b.sy)>=0	&&	\
		 crossp(b.sx-a.sx,b.sy-a.sy,a.ex-a.sx,a.ey-a.sy)*crossp(a.ex-a.sx,a.ey-a.sy,b.ex-a.sx,b.ey-a.sy)>=0)	return	1;
	else	return	0;
}

int main(){
	int vv;
	scanf("%d",&vv);
	while	(vv--){
		scanf("%lf%lf%lf%lf",&s1.sx,&s1.sy,&s1.ex,&s1.ey);
		scanf("%lf%lf%lf%lf",&s2.sx,&s2.sy,&s2.ex,&s2.ey);
		if	(s1.sy>s1.ey){
			swap(s1.sx,s1.ex);
			swap(s1.sy,s1.ey);
		}
		if	(s2.sy>s2.ey){
			swap(s2.sx,s2.ex);
			swap(s2.sy,s2.ey);
		}
		if	(!cross(s1,s2)){
			printf("0.00\n");
			continue;
		}
		if	(eq(s1.sy,s1.ey) || eq(s2.sy,s2.ey)){
			printf("0.00\n");
			continue;
		}
		double k1=slope(s1.sx,s1.sy,s1.ex,s1.ey);
		double k2=slope(s2.sx,s2.sy,s2.ex,s2.ey);
		if	(eq(k1,k2)){
			printf("0.00\n");
			continue;
		}
		double b1=s1.sy-k1*s1.sx;
		double b2=s2.sy-k2*s2.sx;
		double meetx=(b2-b1)/(k1-k2);
		double meety=meetx*k1+b1;
		double h=min(s1.ey,s2.ey);
		double d=abs((h-b1)/k1-(h-b2)/k2);
		//printf("%.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf\n",k1,b1,k2,b2,meetx,meety,h,d);
		if	(k1*k2>0)
			if	(abs(k1)>abs(k2)){
				if	(abs(s1.ex-meetx)>=abs(s2.ex-meetx)){
					printf("0.00\n");
					continue;
				}
			}
			else
				if	(abs(s1.ex-meetx)<=abs(s2.ex-meetx)){
					printf("0.00\n");
					continue;
				}
		printf("%.2lf\n",0.5*d*(h-meety)+EPS);
	}
}

  

posted @ 2013-01-18 20:44  JS_Shining  阅读(353)  评论(0编辑  收藏  举报