zoukankan      html  css  js  c++  java
  • ZOJ3720 Magnet Darts(点在多边形内)

    第一道点在多边形内的判断题,一开始以为是凸的。其实题意很简单的啦,最后转化为判断一个点是否在一个多边形内。

    如果只是简单的凸多边形的话,我们可以枚举每条边算下叉积就可以知道某个点是不是在范围内了。但对于更一般的多边形,要采用的方法可能就要复杂一些,其中一种是叫做射线法的东西,在该点上画一条射线,如果射线与多边形偶数次相交,则说明点在多边形外,否则在多边形内。实践中可以取水平的一条,至于怎么判断就要看下代码了,判断的过程中如何发现点已经在多边形上了则直接返回。

    计算几何做的少,则是算是补充了一个盲区吧。

    #pragma warning(disable:4996)
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    #define mod 1000000007
    #define maxn 1000000
    #define eps 1e-6
    using namespace std;
    
    struct Point
    {
    	int x, y;
    	Point(int xi, int yi) :x(xi), y(yi){}
    	Point(){}
    	int dot(const Point &b){
    		return x*b.x + y*b.y;
    	}
    	int det(const Point &b){
    		return x*b.y - y*b.x;
    	}
    	Point operator - (const Point &b){
    		return Point(x - b.x, y - b.y);
    	}
    }p[25];
    
    int dcmp(double x){
    	return (x > eps) - (x < -eps);
    }
    
    int n;
    double A, B;
    double lx, rx, ly, ry;
    
    bool onLine(Point x, Point aa, Point bb)
    {
    	return (bb - aa).det(x-aa) == 0 && (bb - x).dot(aa - x) <= 0;
    }
    
    bool inside(Point x)
    {
    	int ret = 0;
    	for (int i = 0; i < n; i++){
    		if (onLine(x, p[i], p[(i + 1) % n])) return true;
    		int k = (p[(i + 1) % n] - p[i]).det(x - p[i]);
    		int d1 = x.y - p[i].y;
    		int d2 = x.y - p[(i + 1) % n].y;
    		if (k > 0 && d1 >= 0 && d2 < 0) ret++;
    		if (k < 0 && d2 >= 0 && d1 < 0) ret--;
    	}
    	return ret != 0;
    }
    
    int main()
    {
    	while (cin>>lx>>ly>>rx>>ry){
    		scanf("%d%lf%lf", &n, &A, &B);
    		for (int i = 0; i < n; i++){
    			scanf("%d%d", &p[i].x, &p[i].y);
    		}
    		p[n].x = p[0].x; p[n].y = p[0].y;
    		double ans = 0;
    		int llx = ceil(lx), rrx = floor(rx);
    		int lly = ceil(ly), rry = floor(ry);
    
    		for (int i = llx; i <= rrx; i++){
    			for (int j = lly; j <= rry; j++){
    				if (inside(Point(i, j))){
    					double h = min(i + 0.5, rx) - max(i - 0.5, lx);
    					double w = min(j + 0.5, ry) - max(j - 0.5, ly);
    					ans += (A*i + B*j)*h*w;
    				}
    			}
    		}
    		ans /= (double)(rx - lx)*(ry - ly);
    		printf("%.3lf
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    spring boot打包出现yaml配置文件问题
    spring boot定时器使用异常
    常见mysql死锁案例行死锁与表死锁
    数据库三范式
    【leetcode】26. 删除排序数组中的重复项
    【数据结构与算法】10.2 二叉排序树
    【设计模式】5、适配器设计模式之对象适配器
    【数据结构与算法】10.1、赫夫曼树代码实现
    【设计模式】4、建造者模型以及Stringbuilder源码分析
    【设计模式】2、工厂模式之简单工厂、方法工厂、抽象工厂
  • 原文地址:https://www.cnblogs.com/chanme/p/3634396.html
Copyright © 2011-2022 走看看