POJ 1265 pick定理

pick公式:多边形的面积=多边形边上的格点数目/2+多边形内部的格点数目-1。

多边形边上的格点数目可以枚举每条边求出。如果是水平或者垂直,显然可以得到,否则则是坐标差的最大公约数减1.(注这里是不计算端点的,端点必然在格点上,最后统计)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <map>
#include <sstream>
#include <queue>
#include <vector>
#define MAXN 111111
#define MAXM 211111
#define PI acos(-1.0)
#define eps 1e-8
#define INF 1000000001
using namespace std;
int dblcmp(double d)
{
    if (fabs(d) < eps) return 0;
    return d > eps ? 1 : -1;
}
struct point
{
    double x, y;
    point(){}
    point(double _x, double _y):
    x(_x), y(_y){};
    void input()
    {
        scanf("%lf%lf",&x, &y);
    }
    double dot(point p)
    {
        return x * p.x + y * p.y;
    }
    double distance(point p)
    {
        return hypot(x - p.x, y - p.y);
    }
    point sub(point p)
    {
        return point(x - p.x, y - p.y);
    }
    double det(point p)
    {
        return x * p.y - y * p.x;
    }
    bool operator < (point a)const
    {
        return dblcmp(a.x - x) == 0 ? dblcmp(y - a.y) < 0 : x < a.x;
    }

}p[MAXN];

int n;
double getarea()
{
    double res = 0;
    for(int i = 1; i < n; i++) res += p[i].sub(p[0]).det(p[i + 1].sub(p[0]));
    res = fabs(res) / 2;
    return res;
}
int getinedge()
{
    int ans = 0;
    for(int i = 1; i <= n; i++)
    {
        int x = (int)fabs(p[i].x - p[i - 1].x);
        int y = (int)fabs(p[i].y - p[i - 1].y);
        if(x == 0 && y == 0) continue;
        if(x == 0) ans += y - 1;
        else if(y == 0) ans += x - 1;
        else ans += __gcd(x, y) - 1;
    }
    return ans + n;
}
int main()
{
    int T;
    double x, y;
    int cas = 0;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        p[0].x = 0, p[0].y = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%lf%lf", &x, &y);
            p[i].x = p[i - 1].x + x;
            p[i].y = p[i - 1].y + y;
        }
        double area = getarea();
        int inedge = getinedge();
        int inside = (int)area + 1 - inedge / 2;
        printf("Scenario #%d:
%d %d %.1f

",++cas, inside, inedge, area);
    }
    return 0;
}


原文地址:https://www.cnblogs.com/keanuyaoo/p/3402526.html