【题目大意】:给出一个矩形的左上角的点(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;
}
本文介绍了一种通过线段切割矩形的算法,利用叉积判断点的位置来确定每块区域内的点数,并统计含有特定数量点的区域数目。代码采用C++实现。
815

被折叠的 条评论
为什么被折叠?



