Codeforces-GYM101873:Water Testing(皮克定理)

Codeforces-GYM101873:Water Testing(皮克定理)_第1张图片

思路:利用皮克定理 2S=2n+m2 2 ∗ S = 2 ∗ n + m − 2
其中n表示多边形内部的整点数,m表示多边形边界上的整点数,S表示多边形的面积。
还有就是线段2点 (x1,y1) ( x 1 , y 1 ) (x2,y2) ( x 2 , y 2 ) 之间的整点数是 gcd(x1x2,y1y2) g c d ( x 1 − x 2 , y 1 − y 2 )

#include
using namespace std;
const int MAX=1e5+10;
typedef long long ll;
struct Point{int x,y;}p[MAX];
Point operator+(Point A,Point B){return (Point){A.x+B.x,A.y+B.y};}        //vector A+B
Point operator-(Point A,Point B){return (Point){A.x-B.x,A.y-B.y};}        //vector A-B
ll operator^(Point A,Point B){return 1ll*A.x*B.y-1ll*A.y*B.x;}            //corss(A,B)
ll Polyarea(Point *p,int n)
{
    ll area=0;
    for(int i=1;i1;i++)area+=(p[i]-p[0])^(p[i+1]-p[0]);
    return abs(area);
}
int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
int cal(Point A,Point B)
{
    if(A.x==B.x)return abs(A.y-B.y)-1;
    if(A.y==B.y)return abs(A.x-B.x)-1;
    return gcd(abs(B.y-A.y),abs(B.x-A.x))-1;
}
int main()
{
    int n;
    cin>>n;
    for(int i=0;iscanf("%d%d",&p[i].x,&p[i].y);
    ll S=Polyarea(p,n);
    ll m=n;
    for(int i=0;i1)%n]);
    printf("%lld\n",(S-m+2)/2);
}

你可能感兴趣的:(计算几何)