计算几何-点、线、面、形

1.TOYS

双语描述:

Calculate the number of toys that land in each bin of a partitioned toy box.
计算一个分区玩具箱每个箱子里的玩具数量。
Mom and dad have a problem - their child John never puts his toys away when he is finished playing with them. They gave John a rectangular box to put his toys in, but John is rebellious and obeys his parents by simply throwing his toys into the box. All the toys get mixed up, and it is impossible for John to find his favorite toys.
妈妈和爸爸有一个问题-他们的孩子约翰从来没有把他的玩具,当他结束了与他们玩。他们给约翰一个长方形的盒子,把他的玩具放在里面,但是约翰很叛逆,服从他的父母,只是把他的玩具扔到盒子里。所有的玩具都搞混了,约翰不可能找到他最喜欢的玩具。
John's parents came up with the following idea. They put cardboard partitions into the box. Even if John keeps throwing his toys into the box, at least toys that get thrown into different bins stay separated. The following diagram shows a top view of an example toy box.
约翰的父母想出了如下主意。他们在盒子里放了硬纸板隔板。即使约翰不停地把玩具扔到盒子里,至少把玩具扔进不同的垃圾箱会被分开。下图显示了示例玩具盒的俯视图。
For this problem, you are asked to determine how many toys fall into each partition as John throws them into the toy box.
对于这个问题,你被要求确定有多少玩具落入每个分区,当约翰把它们扔到玩具盒里时。
View Code

代码:

#include <stdio.h>
#include <math.h>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 5001
#define MAX 1<<30
#define V vector<int>

using namespace std;

typedef struct Point{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y){
    }
}Point;

Point operator - (Point a,Point b){
    return Point(a.x-b.x,a.y-b.y);
}

Point spl[LEN][2],pt[LEN];
Point pt1,pt2;
int ans[LEN];

double dot(Point a,Point b){
    return a.x*b.x+a.y*b.y;
}

double cross(Point a,Point b){
    return a.x*b.y-a.y*b.x;
}

int n,m;

int main(){
//    freopen("D:\\CbWorkspace\\计算几何\\toys.txt","r",stdin) ;
    int i,j;
    bool is_s=1;
    while(1){
        memset(ans,0,sizeof ans);
        I("%d",&n);
        if(n==0) exit(0);
        else{
            if(is_s){
                is_s=0;
            }else{
                puts("");
            }
        }
        scanf("%d %lf %lf %lf %lf",&m,&pt1.x,&pt1.y,&pt2.x,&pt2.y);
        F(i,1,n+1){
            I("%lf%lf",&spl[i][0].x,&spl[i][1].x);
            spl[i][0].y=pt1.y;
            spl[i][1].y=pt2.y;
        }
        spl[0][0]=pt1;
        spl[0][1]=pt1;
        spl[0][1].y=pt2.y;
        spl[n+1][0]=pt2;
        spl[n+1][1]=pt2;
        spl[n+1][1].y=pt1.y;
        FF(i,m){
            scanf("%lf%lf",&pt[i].x,&pt[i].y);
        }
        FF(i,m){
            int l=0,u=n+1,mid=(l+u)/2;
            while(u-l>1){
                Point v1=spl[mid][0]-pt[i];
                Point v2=spl[mid][1]-pt[i];
                double c=cross(v1,v2);
                if(c<0){//point left of mid
                    u=mid;
                    mid=(l+mid)/2;
                }else{
                    l=mid;
                    mid=(u+mid)/2;
                }
            }
            ans[l]++;
        }
        for(i=0;i<=n;i++)
            printf("%d: %d\n",i,ans[i]);
    }

}
View Code

解题思想:向量积判断左右 + 二分

了解数量积,向量积的几何意义

本题的解题技巧

示意图:

用向量积判断点在边的左侧还是右侧:

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

PA¯¯¯¯¯×PB¯¯¯¯¯<0

posted @ 2018-02-12 12:31  TQCAI  阅读(238)  评论(0编辑  收藏  举报