这种1A的感觉真好
1 #include <cstdio> 2 #include <vector> 3 #include <cmath> 4 using namespace std; 5 typedef long long LL; 6 7 struct Point 8 { 9 LL x, y; 10 Point(LL x=0, LL y=0):x(x), y(y) {} 11 }; 12 13 Point operator - (const Point& A, const Point& B) 14 { return Point(A.x-B.x, A.y-B.y); } 15 16 LL Cross(const Point& A, const Point& B) 17 { return A.x*B.y-A.y*B.x; } 18 19 typedef vector<Point> Polygon; 20 21 LL Area(const Polygon& p) 22 { 23 LL ans = 0; 24 int n = p.size(); 25 for(int i = 1; i < n-1; i++) ans += Cross(p[i]-p[0], p[i+1]-p[0]); 26 return abs(ans/2); 27 } 28 29 LL gcd(LL a, LL b) { return b == 0 ? a : gcd(b, a%b); } 30 31 LL Boundary(const Polygon& p) 32 { 33 LL ans = 0; 34 int n = p.size(); 35 for(int i = 0; i < n-1; i++) 36 { 37 LL a = abs(p[i+1].x - p[i].x); 38 LL b = abs(p[i+1].y - p[i].y); 39 ans += gcd(a, b); 40 } 41 ans += abs(gcd(p[n-1].x-p[0].x, p[n-1].y-p[0].y)); 42 return ans; 43 } 44 45 int main() 46 { 47 //freopen("in.txt", "r", stdin); 48 int n; 49 while(scanf("%d", &n) == 1 && n) 50 { 51 Polygon poly; 52 Point p; 53 for(int i = 0; i < n; i++) 54 { 55 scanf("%lld%lld", &p.x, &p.y); 56 poly.push_back(p); 57 } 58 LL A = Area(poly); 59 LL b = Boundary(poly); 60 printf("%lld ", A - b/2 + 1); 61 } 62 63 return 0; 64 }
假设平面上有一个顶点均为格点的单纯多边形(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级数中的应用,留坑,以后再看。