Description
A lattice point is an ordered pair (x, y) where x and y are both integers. Given the coordinates of the vertices of a triangle (which happen to be lattice points), you are to count the number of lattice points which lie completely inside of the triangle (points on the edges or vertices of the triangle do not count).
Input
The input test file will contain multiple test cases.
Each input test case consists of six integers
x1,y1,x2,y2,x3
,and
y3
, where
(x1,y1),(x2,y2)
, and
(x3,y3)
are the coordinates of vertices of the triangle. All triangles in the input will be non-degenerate (will have positive area), and
−15000≤x1,y1,x2,y2,x3,y3≤15000
.
The end-of-file is marked by a test case with
x1=y1=x2=y2=x3=y3=0
and should not be processed.
Output
For each input case, the program should print the number of internal lattice points on a single line.
Sample Input
0 0 1 0 0 1
0 0 5 0 0 5
0 0 0 0 0 0
Sample Output
0
6
Source
Stanford Local 2004
题目大意
给你一个网格三角形的三个顶点坐标(都是格点),求在这个三角形里的格点有多少个(不包含在三角形边上的格点)
多组数据,以0 0 0 0 0 0结束
solution
只要你知道Pick定理和叉积,这道题就和a+b一样简单
Pick定理: s=a+b2−1
s 表示顶点在格点上的网格多边形的面积
a 表示在多边形内部的格点的数量, b 表示在多边形边上的格点的数量证明什么的
tanπ2 ,自己画几个验证一下吧….叉积算三角形面积,还是画图说吧…
我们知道 |AB→×AC→|=SACDB ,其中 × 表示叉积
所以 S△ABC=SACDB2=|AB→×AC→|2
然后现在要想算 a ,就只剩下
b 还不知道了,来考虑怎么算 b还是上面那个图,假设我们要算
AB 这条边经过的格点,那就是 gcd(abs(xA−xB),abs(yA−yB))证明依旧 tanπ2 ,
等我会证了我一定会回来补上的QAQ
code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
template<typename T>
void input(T &x) {
x=0; T a=1;
register char c=getchar();
for(;c<'0'||c>'9';c=getchar())
if(c=='-') a=-1;
for(;c>='0'&&c<='9';c=getchar())
x=x*10+c-'0';
x*=a;
return;
}
struct Vector {
int x,y;
Vector(int x=0,int y=0):
x(x),y(y) {}
int operator *(const Vector &q) {
return abs(x*q.y-q.x*y);
}
};
struct Point {
int x,y;
Point(int x=0,int y=0):
x(x),y(y) {}
void SCAN() {
input(x),input(y);
return;
}
Vector operator - (const Point &q) const {
return Vector(x-q.x,y-q.y);
}
};
Point a,b,c;
int gcd(int a,int b) {
return !b?a:gcd(b,a%b);
}
int calc(Point a,Point b) {
return gcd(abs(a.x-b.x),abs(a.y-b.y));
}
int main() {
int S,B,A;
while(true) {
a.SCAN(),b.SCAN(),c.SCAN();
if(!a.x&&!b.x&&!c.x&&!a.y&&!b.y&&!c.y)
break;
S=((a-b)*(a-c))/2;
B=calc(a,b)+calc(a,c)+calc(b,c);
A=S-B/2+1;
printf("%d\n",A);
}
return 0;
}