poj 2318 暴力+叉积判断

题意:给定一个如下图所示的长方形箱子(俯视图),中间有n条线段,将其分为n+1个区域,给定m个玩具的坐标,统计每个区域中的玩具个数。

解答:将点排序,然后从左到右暴搜即可。其中用变量j记录开始搜索的线段,以进行优化。

另外的做法:对每个玩具,二分线段下标,判断在线段左边还是右边,找到之后进行统计即可。

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define clr(s,t) memset(s,t,sizeof(s))
#define N 5005
struct point{
    int x,y;
}s[N];
struct line{
    point u,d;
}t[N];
int n,m,x1,x2,y1,y2;
int res[N];
int cmp(point a,point b){
    return a.x < b.x;
}
int multi(point a,point b,point c){
    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
int main(){
    while(scanf("%d",&n) && n){
        int i,j,k;
        clr(res, 0);
        scanf("%d %d %d %d %d",&m,&x1,&y1,&x2,&y2);
        for(i = 1;i<=n;i++){
            scanf("%d %d",&t[i].u.x,&t[i].d.x);
            t[i].u.y = y1;
            t[i].d.y = y2;
        }
        for(i = 1;i<=m;i++)
            scanf("%d %d",&s[i].x,&s[i].y);
        sort(s+1,s+1+m,cmp);
        j = 1;
        for(i = 1;i<=m;i++){
            while(j<=n && s[i].x > max(t[j].u.x,t[j].d.x))
                j++;
            for(k = j;k<=n && multi(t[k].u,t[k].d,s[i])>0;k++)
                ;
            res[k-1]++;
        }
        for(i = 0;i<=n;i++)
            printf("%d: %d\n",i,res[i]);
        printf("\n");
    }
    return 0;
}


你可能感兴趣的:(poj 2318 暴力+叉积判断)