poj1265

来源:互联网 发布:南师大艺考成绩算法 编辑:程序博客网 时间:2024/05/01 12:05

[Pick定理]   


pick定理:                设F为平面上以格子点为定点的单纯多边形,则其面积为:S=b/2+i-1。                 b为多边形边上点格点的个数,i为多边形内部格点的个数。 可用其计算多边形的面积,边界格点数或内部格点数。

题目大意:

给你m个dx,dy,注意这个不是直接给出的坐标,而是沿着x轴和y轴所走的距离,所以当前的坐标就是把前面的数据都加起来,又因为是一个闭合的,所以我们可以假设起点是(0,0)。然后根据上面的公式计算内部点。 

代码:

#include <iostream>#include <cstdio>#include <cstdlib>//#include <cstring>#include <cmath>using namespace std;struct POINT {int x,y;}point[110];int n;double getArea(){double sum = 0;for (int i = 0; i < n; ++ i){sum += (point[i].x   * point[(i + 1) % n].y   - point[i].y  * point[(i + 1) % n].x );}return fabs(sum/2.0);}int Gcd(int a, int b){if (0 == b){return a;}elsereturn Gcd(b, a % b);}int getSegmentPoint(POINT p1, POINT p2){int a = abs(p2.y - p1.y);int b = abs(p2.x - p1.x);if (a == 0 && b == 0){return 0;}if (a == 0){return b - 1;}if (b == 0){return a - 1;}return Gcd(b, a) - 1;}int getPoint(){int ans = n;for (int i = 0; i < n; ++ i){ans += getSegmentPoint(point[i], point[(i + 1) % n]);}return ans;}int main(){int cas, j = 1;scanf("%d", &cas);while (cas --){scanf("%d", &n);point[0].x = point[0].y = 0;for (int i = 1; i <= n; ++ i){scanf("%d %d", &point[i].x, &point[i].y);point[i].x += point[i - 1].x;point[i].y += point[i - 1].y;//cin >> point[i].x >> point[i].y;}printf("Scenario #%d:\n", j ++);double Area = getArea();int res;int PointNum = getPoint();res = (int)Area - PointNum / 2 + 1;printf("%d %d %.1lf\n\n", res, PointNum, Area);}return 0;}