poj 1265 Area

来源:互联网 发布:java怎么做界面设计 编辑:程序博客网 时间:2024/05/22 07:05

/*

题意: 求逆时针顺序的顶点为整点的简单多边形边面积A, 其边上的格点数, 内部的格点数。 

Pick定理:A = I + E/ 2 - 1(前提为顶点为整数)

一开一闭区间(x1, y1)-> (x2, y2)的上的格子点数为 gcd(|x1 - x2|, |y1 - y2|);

然后就可以水了, G++输出“%.1f”   C++输出 “%.1lf” 不然就会WA

*/


#include <iostream>#include <cstdio>#include <queue>#include <algorithm>#define MAX 1005#include <complex>#include <ctime>#include <cstdlib>#include <cstring>#include <string>#define INF 1e8#define MAX (int)1e6+ 5using namespace std;inline int gcd(int a, int b){ return !b? a : gcd(b, a % b);}struct Point{  int x, y;  Point(){}  Point(int xx , int yy):x(xx), y(yy){}  Point operator - ( const Point &a)const {    return Point(x - a.x, y - a.y);  }  friend int det(const Point &a, const Point &b){    return a.x * b.y - a.y * b.x;  }  void in(){ scanf("%d %d", &x, &y);}  void out(){cout<<x<<" "<<y<<endl;}};struct Polygon{    vector<Point>p;//anti-clockwis    int E, I;    double A;    Polygon(){}    Polygon(const vector<Point> &a):p(a){ }    void caAEI(){        int n = p.size();        A = 0;        E = 0;        #define next(i) ( (i + 1) % n)        for(int i = 0; i < n; i++){            int ni = next(i);            A += det(p[i], p[ni]);            E += gcd(abs(p[i].x - p[ni].x), abs(p[i].y - p[ni].y) );        }         A /= 2.0;//pick定理, A = I + E/2 - 1;         I = (int)(A + 1 - E/ 2.0);    }    void out(){        printf("%d %d %.1f\n", I, E, A);    }};int T, n;int main(){    cin>>T;    int ca = 0;    while(T--){        cin>>n;        vector<Point>temp;        Point now(0, 0), dir;        for(int i = 0; i < n; i++){            dir.in(); dir = Point(0, 0) - dir;            now = now - dir;            temp.push_back(now);        }        Polygon pg(temp);        pg.caAEI();        printf("Scenario #%d:\n", ++ca);        pg.out();        cout<<endl;    }    return 0;}