| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 10848 | Accepted: 5206 |
Description
Input
Output
Sample Input
5 6 0 10 60 0 3 1 4 3 6 8 10 10 15 30 1 5 2 1 2 8 5 5 40 10 7 9 4 10 0 10 100 0 20 20 40 40 60 60 80 80 5 10 15 10 25 10 35 10 45 10 55 10 65 10 75 10 85 10 95 10 0
Sample Output
0: 2 1: 1 2: 1 3: 1 4: 0 5: 1 0: 2 1: 2 2: 2 3: 2 4: 2
Hint
题目很简单,判断一下点与线段关系,枚举线段时,可以按区间二分枚举,左右边界。
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
using namespace std;
#define N 5005
#define ll long long
int n,cnt[N];
struct p
{
int x,y;
}a,b,c,up[N],down[N];
double cross(p a,p b,p c)
{
return 1.0*(b.x-a.x)*(c.y-a.y)-1.0*(c.x-a.x)*(b.y-a.y);
}
int judge(p a)
{
int l=1,r=n,mid;
while(l<=r)
{
mid=(l+r)>>1;
double s1=cross(a,down[mid-1],up[mid-1]);
double s2=cross(a,down[mid],up[mid]);
//printf("%d %.3f %.3f\n",mid,s1,s2);
if(s1*s2<0)
return mid;
if(s2<0)
l=mid+1;
else
r=mid-1;
}
return l;
}
int main()
{
int i,t,m;
while(scanf("%d",&n),n)
{
scanf("%d%d%d%d%d",&m,&b.x,&b.y,&c.x,&c.y);
up[0].x=down[0].x=b.x; //box起始点
up[0].y=up[n+1].y=b.y;
up[n+1].x=down[n+1].x=c.x; //box终点
down[0].y=down[n+1].y=c.y;
for(i=1;i<=n;i++)
{
scanf("%d%d",&up[i].x,&down[i].x);
up[i].y=b.y;
down[i].y=c.y;
}
n++;
memset(cnt,0,sizeof(cnt));
while(m--)
{
scanf("%d%d",&a.x,&a.y);
t=judge(a); // 二分判断位置关系
cnt[t]++;
}
for(i=0;i<n;i++)
{
printf("%d: %d\n",i,cnt[i+1]);
}
puts("");
}
return 0;
}
原文:http://blog.csdn.net/u011721440/article/details/41774839