http://poj.org/problem?id=1265
定理证明见Matrix67——最酷的证明:Pick定理另类证法
注意dx和dy是机器人下一步移动的方向,所以位置要累加。
完整代码:
/*0ms,372KB*/
#include<cstdio>
#include<cstdlib>
const int mx = 105;
struct point
{
double x, y;
point(double x = 0.0, double y = 0.0): x(x), y(y) {}
void read() const
{
scanf("%lf%lf", &x, &y);
}
};
point a[mx];
int n;
///oa x ob
inline double cross_product(point& a, point& b)
{
return a.x * b.y - a.y * b.x;
}
///求多边形面积。以原点为向量起点。注意ans[]要是顺时针顺序
double area()
{
double sum = 0.0;
a[n] = a[0];
for (int i = 0; i < n; ++i) sum += cross_product(a[i], a[i + 1]);
return sum / 2.0;
}
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int borderpoint()
{
int cnt = 0;
a[n] = a[0];
for (int i = 0; i < n; ++i)
cnt += gcd(abs((int)(a[i].x - a[i + 1].x)), abs((int)(a[i].y - a[i + 1].y)));
return cnt;
}
int main()
{
int t, i, B;
double A;
scanf("%d", &t);
for (int k = 1; k <= t; ++k)
{
scanf("%d", &n);
for (i = 1; i < n; ++i)
{
a[i].read();
a[i].x += a[i - 1].x;
a[i].y += a[i - 1].y;
}
scanf("%*d%*d");
A = area();
B = borderpoint();
printf("Scenario #%d:\n%d %d %.1f\n\n", k, (int)A + 1 - B / 2, B, A);
}
return 0;
}