zoukankan      html  css  js  c++  java
  • 【bzoj5008】方师傅的房子 计算几何

    题目描述

    给出一个凸多边形,多次询问某个点是否在这个凸多边形的内部,强制在线。

    输入

    第一行一个数n,接下来n行,每行两个整数x,y。输入按照逆时针顺序输入一个凸包。  
    接下来一个数m,最后有m行,第一行两个整数 x,y,表示第一个人的坐标。
    对于第i个询问(i>=2) ,输入两个数dx,dy。
    如果上一个人在房子内部,x[i]=x[i-1]+dx,y[i]=y[i-1]+dy。否则x[i]=x[i-1]-dx,y[i]=y[i-1]-dy。
    n <= 100000, m <= 200000,输入保证所有人的坐标,房屋的坐标都在[-1e9,1e9]之内。

    输出

    输出一个数,在房子内部人的个数。

    样例输入

    4
    -2 -2
    2 -2
    2 2
    -2 2
    3
    5 5
    4 4
    0 3

    样例输出

    1


    题解

    计算几何的经典应用

    固定一个点,将其它的点与它的连线按照极角排序,将多边形三角剖分。

    然后查询一个点是否在多边形内部,首先与固定的点连线,找到极角的前驱后继,问题转化为判断是否在前驱后继以及固定点围成的三角形内。可以通过求面积的方法来判断。

    然而我这个傻逼写了set。。。还选了最低的点。。。其实不必要的。。。

    时间复杂度$O(nlog n)$

    #include <set>
    #include <cmath>
    #include <cstdio>
    #include <utility>
    using namespace std;
    typedef pair<double , int> pr;
    set<pr> s;
    set<pr>::iterator it;
    double px[100010] , py[100010] , vx , vy = 1e10;
    inline double calc(double x1 , double y1 , double x2 , double y2)
    {
    	return fabs(x1 * y2 - x2 * y1);
    }
    bool judge(double x , double y)
    {
    	int p , q;
    	it = s.lower_bound(pr(atan2(y - vy , x - vx) , 0));
    	if(it == s.end() || it == s.begin()) return 0;
    	p = it->second , q = (--it)->second;
    	return fabs(calc(px[p] - vx , py[p] - vy , px[q] - vx , py[q] - vy)
    		      - calc(px[p] - x , py[p] - y , px[q] - x , py[q] - y)
    		      - calc(px[p] - x , py[p] - y , vx - x , vy - y)
    		      - calc(px[q] - x , py[q] - y , vx - x , vy - y)) < 1e-8;
    }
    int main()
    {
    	int n , m , i , last = 1 , ans = 0;
    	double lx = 0 , ly = 0 , x , y;
    	scanf("%d" , &n);
    	for(i = 1 ; i <= n ; i ++ )
    	{
    		scanf("%lf%lf" , &px[i] , &py[i]);
    		if(vy > py[i]) vx = px[i] , vy = py[i];
    	}
    	for(i = 1 ; i <= n ; i ++ )
    		s.insert(pr(atan2(py[i] - vy , px[i] - vx) , i));
    	scanf("%d" , &m);
    	while(m -- )
    	{
    		scanf("%lf%lf" , &x , &y);
    		if(last) lx += x , ly += y;
    		else lx -= x , ly -= y;
    		last = judge(lx , ly) , ans += last;
    	}
    	printf("%d
    " , ans);
    	return 0;
    }
    

     

  • 相关阅读:
    ActionBar Fragment的一个sample activity; 及获取runningAppProcess及跳转
    优化后台推送的service,减少被杀死的几率
    64位win7安装ubunto最新14.04的过程,及出现的问题的解决
    一次非线上iowait高的情况的检查
    一个愚蠢的python逻辑语法错误
    Bellman-Ford算法解决单源最短路问题
    Floyd算法解决多源最短路径问题
    最短路问题Dijkstra算法
    最小生成树之Kruskal算法
    最优二叉搜索树
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7883787.html
Copyright © 2011-2022 走看看