( 算法树之几何 )【 皮克定理 】

( 算法树之几何  )【 皮克定理 】

皮克定理是有关格点多边形的面积计算问题,因此在了解皮克定理前,我们要先看一下什么是格点多边形:

一、格点多边形
如图,每个小正方形的边长是1,图中的小正方形的顶点称为"格点",如果一个多边形的每个顶点都在格点上,则称该多边形为"格点多边形",如下图所示是格点四边形。

1899年,奥地利数学家乔治亚历山大匹克对格点多边形面积计算问题给出了以下公式:格点多边形面积=内点数+边界点数÷2-1,如果用m表示内点数,n表示边界点数即:S=m+n÷2-1
这个结论我们称作匹克定理。用它来计算格点多边形方便多了。

这么求边界点数?

1、对于两端点(x1,y1),(x2,y2)都再格点上的一条线段,该线段上的格点数目为gcd( |x1-x2|,|y1-y2| )+ 1,这很好理解,对于横坐标差值和纵坐标差值求得的最大公因数g,相当于将横坐标差值分成g份,由于是整除,因此显然每份的左右端点都是整数,对于纵坐标也是同样的道理,由于是最大公因数,所以不可能再分更多份,因此gcd( |x1-x2|,|y1-y2| )
即求得两端点间最多能分成多少段由格点分割的线段,再加上1即整条线段上的格点数目。

 

例题1:Gym 101873G

题意:按照顺时针给出n个点,点的坐标为整数,求n个点围成的凸多边形内部有几个点xy都是整数。

思路:就是求内点数,多边形面积可以求出,边界点数也可以求出。

代码:

#include <bits/stdc++.h>
#define int long long

using namespace std;

int x[200002],y[200002];
int n;

signed main()
{
    cin >> n;
    for ( int i=0; i<n; i++ ) scanf("%lld %lld",&x[i],&y[i]);
    x[n]=x[0]; y[n]=y[0];
    int sum = 0, b=0;
    for ( int i=0; i<n; i++ ) {
        sum += (x[i]*y[i+1]-x[i+1]*y[i]);
        b += __gcd( abs(x[i]-x[i+1]), abs(y[i]-y[i+1]) );
    }
    if ( sum<0 ) sum=-sum;
    cout << (sum-b+2)/2 << endl;

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值