<题目链接>

题目大意:

给出矩形4个点和n个挡板俩顶点的位置,这n个挡板将该矩形分成 n+1块区域,再给你m个点的坐标,然你输出每个区域内有几个点。

解题思路:

用叉乘即可简单判断点与直线的位置关系,对每一个点,遍历挡板,直到找到符合的区间为止。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std; const int maxn=+;
int map[maxn+];
int n,m; struct Point
{
int x,y;
Point(int a=,int b=):x(a),y(b){}
Point operator - (const Point&b)const
{
return Point(x-b.x,y-b.y);
} int operator ^(const Point&b)const //重载叉乘符号
{
return x*b.y-y*b.x; //两向量叉乘公式
}
}; struct Line
{
Point a,b;
Line(){}
Line(Point m,Point n):a(m),b(n){}
};
Line arr[maxn+];
Point brr[maxn+];
// 求叉积
int Mulcross(Point p0,Point p1,Point p2)
{
return (p1-p0)^(p2-p0); //计算
} //不一定是这个顺序计算,只要保证两个向量有共同的顶点,和下面的>0判断相应改变即可,你可以以p0或p2为顶点 void juge(Point goal)
{
// 从第一条线向后遍历,如果点在该线左面,则该下标total++
for(int i=;i<n;i++)
{
//这里根据叉乘判断点与直线的方向,主要的依据就是两个向量叉乘的右手定则,若朝平面下,则<0,若朝平面上则>0,然后自己画图理解一下
if(Mulcross(arr[i].b,goal,arr[i].a)>)continue; // 如果点在挡板的右边,则继续看下一个区间是否符合
else
{
map[i]+=; //如果点在挡板的左边,那么当前区间点的个数+1
return;
}
}
// 找到最后都没找到,就是在最后一个区域
map[n]+=;
} int main()
{
int ncase=;
while(scanf("%d",&n)!=EOF,n)
{
memset(map,,sizeof(map));
int marx1,mary1,marx2,mary2;
scanf("%d%d%d%d%d",&m,&marx1,&mary1,&marx2,&mary2);
for(int i=;i<n;i++) //挡板的坐标
{
int x1,x2;
scanf("%d %d",&x1,&x2);
arr[i].a.x=x1;arr[i].a.y=mary1;
arr[i].b.x=x2;arr[i].b.y=mary2;
} for(int i=;i<m;i++) //点的坐标
{
int a,b;
scanf("%d %d",&a,&b);
juge(Point(a,b)); //找到点的区间
} for(int i=;i<=n;i++)
{
printf("%d: %d\n",i,map[i]);
}
printf("\n");
}
return ;
}

二分查找的方法

<转载于>

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <math.h> using namespace std;
struct Point
{
int x,y;
Point(){}
Point(int _x,int _y)
{
x = _x;y = _y;
}
Point operator -(const Point &b)const //向量相减
{
return Point(x - b.x,y - b.y);
}
int operator *(const Point &b)const //向量相乘
{
return x*b.x + y*b.y;
}
int operator ^(const Point &b)const
{
return x*b.y - y*b.x;
}
};
struct Line
{
Point s,e;
Line(){}
Line(Point _s,Point _e)
{
s = _s;e = _e;
}
}; int xMult(Point p0,Point p1,Point p2) //计算p0p1 X p0p2
{
return (p1-p0)^(p2-p0);
} const int MAXN = ;
Line line[MAXN];
int ans[MAXN]; int main()
{
int n,m,x1,y1,x2,y2;
bool first = true;
while(scanf("%d",&n) == && n)
{
if(first)first = false;
else printf("\n");
scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);
int Ui,Li;
for(int i = ;i < n;i++)
{
scanf("%d%d",&Ui,&Li);
line[i] = Line(Point(Ui,y1),Point(Li,y2));
}
line[n] = Line(Point(x2,y1),Point(x2,y2));
int x,y;
Point p;
memset(ans,,sizeof(ans));
while( m-- )
{
scanf("%d%d",&x,&y);
p = Point(x,y);
int l = ,r = n;
int tmp;
while( l <= r)
{
int mid = (l + r)/;
if(xMult(p,line[mid].s,line[mid].e) < )
{
tmp = mid;
r = mid - ;
}
else l = mid + ;
}
ans[tmp]++;
}
for(int i = ; i <= n;i++)
printf("%d: %d\n",i,ans[i]);
}
return ;
}

2018-08-01

05-11 10:52