zoukankan      html  css  js  c++  java
  • 计算几何-点、线、面、形

    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
    ",i,ans[i]);
        }
    
    }
    View Code

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

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

    本题的解题技巧

    示意图:

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


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

  • 相关阅读:
    TCP三次握手过程
    btree b+tree 的关系
    volatile和指令重排序
    事务一致性理解 事务ACID特性的完全解答
    JVM 详解
    java 并发 详解
    socker TCP UDP BIO NIO
    mysql 主从复制 配置
    身份证格式验证 方法
    分布式事务 XA 两段式事务 X/open CAP BASE 一次分清
  • 原文地址:https://www.cnblogs.com/TQCAI/p/8444263.html
Copyright © 2011-2022 走看看