POJ 2954 Triangle(Pick定理)
根据pick定理来做
皮克定理是指一个计算点阵中顶点在格点上的多边形面积公式该公式可以表示为
2S=2a+b−2
其中a表示多边形内部的点数,b表示多边形边界上的点数,S表示多边形的面积。
还有就是求边上的点的话,如果x或y对于零,边上点数等于x+y,否则就加他们的最大公约数。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
double maxx = -1e18;
struct Point
{
int x, y;
Point(int x = 0, int y = 0):x(x),y(y) {}
};
typedef Point Vector;
Vector operator + (Vector A, Vector B)
{
return Vector(A.x+B.x, A.y+B.y);
}
Vector operator - (Point A, Point B)
{
return Vector(A.x-B.x, A.y-B.y);
}
Vector operator * (Vector A, double p)
{
return Vector(A.x*p, A.y*p);
}
Vector operator / (Vector A, double p)
{
return Vector(A.x/p, A.y/p);
}
bool operator < (const Point& a, const Point& b)
{
if(a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
const double eps = 1e-16;
int sgn(double x)
{
if(fabs(x) < eps)
return 0;
if(x < 0)
return -1;
return 1;
}
bool operator == (const Point& a, const Point& b)
{
if(sgn(a.x-b.x) == 0 && sgn(a.y-b.y) == 0)
return true;
return false;
}
double Dot(Vector A, Vector B)
{
return A.x*B.x + A.y*B.y;
}
double Length(Vector A)
{
return sqrt(Dot(A, A));
}
double Angle(Vector A, Vector B)
{
return acos(Dot(A, B)/Length(A)/Length(B));
}
int Cross(Vector A, Vector B)
{
return A.x*B.y-A.y*B.x;
}
double Area2(Point A, Point B, Point C)
{
return Cross(B-A, C-A);
}
Vector Rotate(Vector A, double rad) //rad为弧度 且为逆时针旋转的角
{
return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
}
Vector Normal(Vector A) //向量A左转90°的单位法向量
{
double L = Length(A);
return Vector(-A.y/L, A.x/L);
}
double ToLeftTest(Point a, Point b, Point c)
{
return Cross(b - a, c - a) ;
}
struct Line
{
Point v, p;
Line() {}
Line(Point v, Point p):v(v), p(p) {}
Point point(double t)
{
return v+(p-v)*t;//返回点P = v + (p - v)*t
}
};
Point GetLineIntersection(Point P, Vector v, Point Q, Vector w)
{
Vector u = P-Q;
double t = Cross(w, u)/Cross(v, w);
return P+v*t;
}
bool LineIntersection(Point a, Point b, Point c, Point d) //直线ab与线段cd相交
{
return sgn(Cross(b - a, c - a)) *sgn( Cross(b - a, d - a)) <=0;
}
double DistanceToLine(Point P, Point A, Point B)
{
Vector v1 = B-A, v2 = P-A;
return fabs(Cross(v1, v2)/Length(v1));
}
double PolygonArea(Point* p, int n){//p为端点集合,n为端点个数
double s = 0;
for(int i = 1; i < n-1; ++i)
s += Cross(p[i]-p[0], p[i+1]-p[0]);
if(s <0)
s = -s;
return s;
}
int gcd(int x, int y)
{
if(y)
return gcd(y,x%y);
else return x;
}
int main()
{
Point p[4];
while(scanf("%d%d%d%d%d%d", &p[0].x,&p[0].y,&p[1].x, &p[1].y,&p[2].x,&p[2].y)!=EOF)
{
if(p[0].x == 0 && p[0].y == 0 && p[1].x == 0 && p[1].y == 0&&p[2].x == 0&&p[2].y ==0)
return 0;
double area = PolygonArea(p,3);
int out = 0;
int in = 0;
p[3] = p[0];
for(int i = 0;i<3;i++)
{
Point temp = p[i]-p[i+1];
if(!temp.x || !temp.y)
{
out += abs(temp.x) + abs(temp.y);
}
else
out += gcd(abs(temp.x), abs(temp.y));
}
in = (area +2-out)/2;
printf("%d\n", in);
}
return 0;
}