UVa 10088 (Pick定理) Trees on My Island

时间:2021-01-11 04:48:57

这种1A的感觉真好

 #include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
typedef long long LL; struct Point
{
LL x, y;
Point(LL x=, LL y=):x(x), y(y) {}
}; Point operator - (const Point& A, const Point& B)
{ return Point(A.x-B.x, A.y-B.y); } LL Cross(const Point& A, const Point& B)
{ return A.x*B.y-A.y*B.x; } typedef vector<Point> Polygon; LL Area(const Polygon& p)
{
LL ans = ;
int n = p.size();
for(int i = ; i < n-; i++) ans += Cross(p[i]-p[], p[i+]-p[]);
return abs(ans/);
} LL gcd(LL a, LL b) { return b == ? a : gcd(b, a%b); } LL Boundary(const Polygon& p)
{
LL ans = ;
int n = p.size();
for(int i = ; i < n-; i++)
{
LL a = abs(p[i+].x - p[i].x);
LL b = abs(p[i+].y - p[i].y);
ans += gcd(a, b);
}
ans += abs(gcd(p[n-].x-p[].x, p[n-].y-p[].y));
return ans;
} int main()
{
//freopen("in.txt", "r", stdin);
int n;
while(scanf("%d", &n) == && n)
{
Polygon poly;
Point p;
for(int i = ; i < n; i++)
{
scanf("%lld%lld", &p.x, &p.y);
poly.push_back(p);
}
LL A = Area(poly);
LL b = Boundary(poly);
printf("%lld\n", A - b/ + );
} return ;
}

代码君

假设平面上有一个顶点均为格点的单纯多边形(simple polygon)

其面积为A,边界上的格点数为b,内部格点数为i,则有恒等关系:

A = b/2 + i - 1

链接:

http://episte.math.ntu.edu.tw/articles/sm/sm_25_10_1/page4.html

从问题的抛出,从特殊情况开始猜想,然后修正,最后给出证明。写得很好。

但是没有证明里面提到的“原子三角形”面积为1/2的命题,难道这个是非常显然的吗?=_=||

*:

http://en.wikipedia.org/wiki/Pick%27s_theorem

比较严格的证明,但没有上一篇通俗易懂。

http://www.cut-the-knot.org/ctk/Farey.shtmlFarey%20Series

这个证明没看,但是后面提到了Pick定理在Farey级数中的应用,留坑,以后再看。