poj1265&&2954 [皮克定理 格点多边形]【学习笔记】

Q:皮克定理这种一句话的东西为什么还要写学习笔记啊?

A:多好玩啊...

PS:除了蓝色字体之外都是废话啊...



 Part I

1.顶点全在格点上的多边形叫做格点多边形(坐标全是整数)

2.维基百科

Given a simple polygon constructed on a grid of equal-distanced points (i.e., points with integer coordinates) such that all the polygon‘s vertices are grid points, Pick‘s theorem provides a simple formula for calculating the area A of this polygon in terms of the number i of lattice points in the interior located in the polygon and the number b of lattice points on the boundary placed on the polygon‘s perimeter:[1]

3.看不懂英文?

S=a+b/2-1,其中a表示多边形内部的点数,b表示多边形边界上的点数,s表示多边形的面积。

证明:

1.先证明直角三角形和矩形 在逆用证明任意三角形,归纳法证明任意多边形

2.

From:http://www.matrix67.com/blog/archives/768

最酷的证明:Pick定理另类证法

难以想像,一段小小的证明竟然能比一个瘦小的留着长头发穿黑色短袖T恤紧身牛仔裤边跳边弹吉他的MM还要酷。原来一直以为这个证明已经很酷了,现在显然我已经找到了一个更酷的证明。
    Pick定理是说,假设平面上有一个顶点全在格点上的多边形P,那么其面积S(P)应该等于i+b/2-1,其中i为多边形内部所含的格点数,b是多边形边界上的格点数。绝大多数证明都是用割补的办法重新拼拆多边形。这里,我们来看一个另类的证明。
    假设整个平面是一个无穷大的铁板;在0时间,每个格点上都有一个单位的热量。经过无穷长时间的传导后,最终这些热量将以单位密度均匀地分布在整个铁板上。下面我们试着求多边形P内的热量。考虑多边形的每一条线段e:它的两个端点均在格点上,因此线段e的中点是整个平面格点的对称中心,因而流经该线段的热量收支平衡(这半边进来了多少那半边就出去了多少),即出入该线段的热量总和实际为0。我们立即看到,P的热量其实完全来自于它自身内部的i个格点(的全部热量),以及边界上的b个格点(各自在某一角度范围内传出的热量)。边界上的b个点形成了一个内角和为(b-2)*180的b边形,从这b个点流入P的热量为(b-2)*180/360 = (b-2)/2 = b/2-1。再加上i个内部格点,于是S(P)=i+b/2-1。

Part II

一条端点在格点上的线段覆盖的点数:

gcd(dx,dy) dxdy分别为线段横向占的点数和纵向占的点数

证明:自己随便想想就知道了,和这道题的思想有点像:http://www.cnblogs.com/candy99/p/6074673.html



于是就可以做裸题了....

POJ 2954 三角形内部格点数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int N=105;
const double eps=1e-8;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘; c=getchar();}
    return x*f;
}
inline int sgn(double x){
    if(abs(x)<eps) return 0;
    else return x<0?-1:1;
}
struct Vector{
    int x,y;
    Vector(int a=0,int b=0):x(a),y(b){}
};
typedef Vector Point;
Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
int Cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

int n,x,y,x2,y2,x3,y3,b,s;
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int main(int argc, const char * argv[]){
    while(scanf("%d",&x)!=EOF){
        y=read();x2=read();y2=read();x3=read();y3=read();
        if(!x&&!y&&!x2&&!y2&&!x3&&!y3) break;
        b=s=0;
        b=gcd(abs(x2-x),abs(y2-y))+gcd(abs(x3-x2),abs(y3-y2))+gcd(abs(x3-x),abs(y3-y));
        s=abs(Cross(Vector(x2-x,y2-y),Vector(x3-x,y3-y)));
        printf("%d\n",(s-b+2)/2);
    }

    return 0;
}

POJ1265 给一个平面上的简单多边形,求边上的点,多边形内的点,多边形面积。

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int N=105;
const double eps=1e-8;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘; c=getchar();}
    return x*f;
}
inline int sgn(double x){
    if(abs(x)<eps) return 0;
    else return x<0?-1:1;
}
struct Vector{
    int x,y;
    Vector(int a=0,int b=0):x(a),y(b){}
};
typedef Vector Point;
Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
int Cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

int n,x,y,b,s;
Point poly[N];
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int main(int argc, const char * argv[]){
    int T=read(),cas=0;
    while(T--){
        b=s=0;
        n=read();
        for(int i=1;i<=n;i++){
            x=read();y=read();
            b+=gcd(abs(x),abs(y));
            poly[i]=poly[i-1]+Point(x,y);
            s+=Cross(poly[i],poly[i-1]);
        }
        s=abs(s);
        printf("Scenario #%d:\n",++cas);
        printf("%d %d %.1f\n\n",(s+2-b)/2,b,0.5*s);
    }

    return 0;
}
时间: 2024-10-15 18:36:13

poj1265&&2954 [皮克定理 格点多边形]【学习笔记】的相关文章

POJ 2954 /// 皮克定理+叉积求三角形面积

题目大意: 给定三角形的三点坐标 判断在其内部包含多少个整点 题解及讲解 皮克定理 多边形面积s = 其内部整点in + 其边上整点li / 2 - 1 那么求内部整点就是 in = s + 1 - li / 2 网格中两格点(整点)间经过的格点(整点)数 即边上整点 li +1=两点横向和纵向距离的最大公约数 //求线段ab之间的整点数 int lineSeg(P a,P b) { int dx=abs(a.x-b.x), dy=abs(a.y-b.y); if(dx==0 && dy=

【模板】计几皮克定理 poj1265

题目链接:https://vjudge.net/problem/POJ-1265 题意:在整点网格中给你若干个点,输出围成的面积还有边上的点还有内部(不包括边的点). 这题为了普遍性做模板,所以就直接把所有点存下来了.皮克定理看注释吧 1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const in

[POJ2954&amp;POJ1265]皮克定理的应用两例

皮克定理: 在一个多边形中.用I表示多边形内部的点数,E来表示多边形边上的点数,S表示多边形的面积. 满足:S:=I+E/2-1; 解决这一类题可能运用到的: 求E,一条边(x1,y1,x2,y2)上的点数(包括两个顶点)=gcd(abs(x1-x2),abs(y1-y2))+1; 求S:刚开始做POJ2954的时候莫名其妙一直WA,用了海伦公式求面积,后来又改用割补法,还是WA.发现面积还是用叉积算的好. 在八十中走廊里看过的书都忘光了啊...这么典型的叉积运用都会选择小学方法...不过至今没

POJ 2954 Triangle (皮克定理, 三角形叉乘求面积)

Triangle Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5303 Accepted: 2297 Description A lattice point is an ordered pair (x, y) where x and y are both integers. Given the coordinates of the vertices of a triangle (which happen to be lat

POJ1265——Area(Pick定理+多边形面积)

Area DescriptionBeing well known for its highly innovative products, Merck would definitely be a good target for industrial espionage. To protect its brand-new research and development facility the company has installed the latest system of surveilla

Area---poj1265(皮克定理+多边形求面积)

题目链接:http://poj.org/problem?id=1265 题意是:有一个机器人在矩形网格中行走,起始点是(0,0),每次移动(dx,dy)的偏移量,已知,机器人走的图形是一个多边形,求这个机器人在网格中所走的面积,还有就是分别求多边形上和多边形内部有多少个网格点: 皮克定理: 在一个多边形中.用I表示多边形内部的点数,E来表示多边形边上的点数,S表示多边形的面积. 满足:S:=I+E/2-1; 求E,一条边(x1,y1,x2,y2)上的点数(包括两个顶点)=gcd(abs(x1-x

POJ 1265-Area(计算几何+皮克定理+多边形面积公式)

题目地址:POJ 1265 题意:给定一个格点多边形,求出内部点数in,边上点数on,和面积S. 思路:运用的定理很多. 1.皮克定理:S=in+on/2-1,即in=(2*S+2-on)/2. 2.多边形的面积公式:按顺序求相邻两个点与原点组成的向量的叉积之和. 3.求边上的格点数:以格子点为顶点的线段,覆盖的点的个数为GCD(dx,dy),其中,dxdy分别为线段横向占的点数和纵向占的点数.如果dx或dy为0,则覆盖的点数为dy或dx. #include <stdio.h> #includ

uva10088格点多边形

题目链接: 用皮克定理: 一个计算点阵中顶点在格点上的多边形面积公式:S=a+b/2-1 其中a表示多边形内部的点数,b表示多边形边界上的点数,s表示多边形的面积. 1 #include<cstdio> 2 #include<cmath> 3 #define ll long long 4 using namespace std; 5 struct point 6 { 7 double x,y; 8 }p[1010]; 9 int gcd(int a, int b) 10 { 11

Gym 101873G - Water Testing - [皮克定理]

题目链接:http://codeforces.com/gym/101873/problem/G 题意: 在点阵上,给出 $N$ 个点的坐标(全部都是在格点上),将它们按顺序连接可以构成一个多边形,求该多边形内包含的格点的数目. 题解: 首先,根据皮克定理 $S = a + \frac{b}{2} - 1$,其中 $S$ 是多边形面积,$a$ 是多边形内部格点数目,$b$ 是多边形边界上的格点数目. 那么,我们只要求出 $S$ 和 $b$,就很好求得 $a$ 了: 1.对于两端点 $(x_1,y_