LightOj1418 - Trees on My Island(Pick定理)

Posted 西瓜不懂柠檬的酸

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LightOj1418 - Trees on My Island(Pick定理)相关的知识,希望对你有一定的参考价值。

题目链接:http://lightoj.com/volume_showproblem.php?problem=1418

题意:给你多边形中的顶点,n个点按顺时针或逆时针方向给出,然后求出多边形内部有多少个整数点;

皮克定理:

  在一个多边形中。用I表示多边形内部的点数,E来表示多边形边上的点数,S表示多边形的面积。

  满足:S = I + E/2 - 1;

E,一条边(x1, y1, x2, y2)上的点数(包括两个顶点)= gcd(abs(x1-x2),abs(y1-y2));

#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<stdio.h>
#include<queue>
using namespace std;
#define met(a, b) memset(a, b, sizeof(a))
#define mod 1000000007
typedef long long LL;
///////////////////////////////////////////////////////////////////////////////////////////////
/*
HDU2036题意:有一个多边形,含有n个顶点,按逆时针方向依次给出,求对应的多边形的面积;
*/
const int N = 10005;
struct point
{
    LL x, y;

    point(){}
    point(LL x, LL y):x(x), y(y) {}

    friend LL operator ^(point p, point q)
    {
        return p.x*q.y - p.y*q.x;
    };
}p[N];

LL gcd(LL a, LL b)
{
    return b==0?a:gcd(b, a%b);
}
int main()
{
    int n, T, t = 1;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        for(int i=1; i<=n; i++)
            scanf("%lld %lld", &p[i].x, &p[i].y);
        p[0] = p[n];

        LL S = 0, E = 0;
        for(int i=1; i<=n; i++)
        {
            S += p[i]^p[i-1];
            E += gcd(abs(p[i].x-p[i-1].x), abs(p[i].y-p[i-1].y));
        }
        LL I = (abs(S)- E)/2 + 1;

        printf("Case %d: %lld\\n", t++, I);
    }
    return 0;
}
/*
IN:
1
9
1 2
2 1
4 1
4 3
6 2
6 4
4 5
1 5
2 3
OUT:
Case 1: 8
*/
View Code

 

以上是关于LightOj1418 - Trees on My Island(Pick定理)的主要内容,如果未能解决你的问题,请参考以下文章

lightoj 1119 - Pimp My Ride(状压dp)

uva 122 trees on the level——yhx

[hdu4010]: Query on The Trees

Uva122 Trees on the level

Trees On the Level

Hdu 4010-Query on The Trees LCT,动态树