数论问题(3)

数论问题

这一次我们来讨论讨论计算几何问题

计算几何说难也难,说不难也不难,关键是模板,计算几何有许多的模板,而且许多的问题都要在纸上先写出自己的想法,推导完成后,再转换为代码,其中向量是最为重要的的一个概念。
话不多说先上题目,通过题目去体会计算几何的魅力;
题目:
链接: poj 1269.
这一道题就用到很多模板:

struct point 
{
	double x,y;//点坐标
	point (double x=0,double y=0):x=(x),y=(y){} 
}; 
typedef point vector;//向量坐标
point read_point()//点的读入 
{
	double x,y;
	scanf("%lf %lf",&x,&y);
	return point(x,y);
}
vector operator-(point a,point b) //向量加减 
{
	return vector(a.x-b.x,a.y-b.y);
}


double cross(vector a,vector b)//叉积,注意这里是向量 
{
	return a.x*b.y-b.x*a.y;
} 

point point_inter(point p,vector v,point q,vector w)
{
	vector u=p-q;
	double t=cross(w,u)/cross(v,w);
	return p+v*t;
} 

这里就是这道题目所用到的模板:
我的代码:


#include<stdio.h>
#include<math.h>
struct point
{
	double x,y;
	point(double x=0,double y=0):x(x),y(y){};
};
typedef point vector; 
point read_point()
{
	double x,y;
	scanf("%lf%lf",&x,&y);
	return point(x,y);	
}
vector operator-(point a,point b)
{
	return vector(a.x-b.x,a.y-b.y); 
}
vector operator*(vector a,double b)
{
	return vector(a.x*b,a.y*b); 
}
vector operator+(vector a,vector b)
{
	return vector(a.x+b.x,a.y*b.y); 
}
double Cross(vector a,vector b)
{
	return a.x*b.y-a.y*b.x;
}
point point_inter(point p,vector v,point q,vector w)
{
	vector u=p-q;
	double t=Cross(w,u)/Cross(v,w);
	return p+v*t;
}
int main()
{
	int k;
	scanf("%d",&k);
	point a1,a2,b1,b2;
	printf("INTERSECTING LINES OUTOUT\n");
	while(k--){
		a1=read_point();
		a2=read_point();
		b1=read_point();
		b2=read_point();
		vector a=a2-a1,b=b2-b1;
		if(Cross(a,b)==0){
			if(Cross(b1-a1,b2-a1)==0&&Cross(b1-a2,b2-a2)==0){
				printf("LINE\n");
			}
			else{
				printf("NONE\n");
			}
		} 
		else{
			point ans=point_inter(a1,a1-a2,b1,b1-b2);
			printf("POINT%.2f %.2f\n",ans.x,ans.y);
		}
	}
	printf("END OF OUTPUT");
	return 0;
} 

思路:这里有一个点就是如何去判断它平行,运用叉积的知识先去判断它是否平行,如果是再去判断是否共线,如果不是那就是相交。
(2)题目:
链接: hdu.
这一道题其实就是比较纯粹的数学题,求多边形的面积;
我的代码:


#include<stdio.h>
#include<stdlib.h>
#include<math.h>
//把多边形变成一个一个的三角形,而且都已(0,0)为原点; 
struct point 
{
	int x,y;
}a[110];
double area(struct point q,struct point p)
{
	return q.x*p.y-p.x*q.y;//叉乘计算面积 
}
int main()
{
	int k;
	scanf("%d",&k);
	while(k){
		for(int i=0;i<k;i++){
			scanf("%d %d",&a[i].x,&a[i].y);
		} 
		double sum=area(a[k-1],a[0]);
		for(int i=1;i<k;i++){
			sum+=area(a[i],a[i-1]);//注意最后i==k-1 
		}
		printf("%.11f\n",fabs(sum*0.5));
		scanf("%d",&k);
	}
	return 0;
}

这里的原理是取(0,0)来分割多个三角形,运用叉乘去求三角形的有效面积,再求和;自己在纸上画一下就很清晰了;

本期就到这了,谢谢大家哈(最后说一句:一定一定要将纸上得出的解转换成算法)

上一篇:C语言——结构体和指针学习


下一篇:转 SQL*Plus中使用DATE类型的绑定变量