您的位置:首页 > 其它

POJ 2398 叉积应用

2012-10-24 14:12 351 查看
【题目大意】:给出一个矩形的左上角的点(x1,y1)以及右下角的点(x2,y2),并给出n条线段,线段表示为(l,y1),(r,y2),用于将矩形切割成n+1块,分别标记为0到n。再给出m个点,求包含t(t>0)个点的有几块。

【解题思路】:已知给出三个点a,b,c,通过叉积可以判断c在线段a,b的哪一侧,若叉积小于0,则在线段左侧,等于0,三点共线,大于0,

找出每条线段i的左侧有a[i]个点 线段 i 到 i+1中间就有 a[i+1] - a[i]个点

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int m_max=1005;
const int n_max=1005;
int number[m_max];
int mt[n_max];
struct point
{
	double x,y;
	void init(double xx,double yy)
	{
		x=xx;
		y=yy;
	}
}p[m_max],w[n_max][2];

void init()
{
	memset(number,0,sizeof(number));
}

double det(point a,point b,point c)
{
	double x1=b.x-a.x;
	double y1=b.y-a.y;
	double x2=c.x-a.x;
	double y2=c.y-a.y;
	return x1*y2-x2*y1;
}

int main()
{
	int n,m;
	double x1,x2,y1,y2;
	while(~scanf("%d",&n),n)
	{
		scanf("%d%lf%lf%lf%lf",&m,&x1,&y1,&x2,&y2);
		init();
		w[0][0].init(x1,y2);
		w[0][1].init(x1,y1);
		w[n+1][0].init(x2,y2);
		w[n+1][1].init(x2,y1);
		int i,j;
		for(i=1;i<=n;i++)
		{
			scanf("%lf%lf",&x1,&x2);
			w[i][0].init(x2,y2);
			w[i][1].init(x1,y1);
		}
		for(j=1;j<=m;j++)
		{
			scanf("%lf%lf",&x1,&y1);
			p[j].init(x1,y1);
		}
		int t=0;
		int nmt=0;
		for(i=0;i<=n+1;i++)
		{
			t=0;
			for(j=1;j<=m;j++)
			{
				if(det(w[i][0],w[i][1],p[j])>0)
				{
					t++;
				}
			}
			mt[nmt++]=t;
		}
		sort(mt,mt+nmt);
		for(i=1;i<nmt;i++)
		{
			number[mt[i]-mt[i-1]]++;
		}
		printf("Box\n");
		for(i=1;i<=m;i++)
		{
			if(number[i])
			{
				printf("%d: %d\n",i,number[i]);
			}
		}
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: