POJ2954Triangle
题意:
给三角形的三个顶点(保证是整数),求三角形内部的点数。
思路:
Pick定理模板题,由定理可得:
a
=
S
−
b
2
+
1
\begin{aligned}a=S-\frac{b}{2}+1\end{aligned}
a=S−2b+1。
用叉积求面积,可得
a
=
∣
A
B
→
×
A
C
→
∣
−
b
2
+
1
\begin{aligned}a=\frac{|\overrightarrow{AB}\times\overrightarrow{AC}|-b}{2}+1\end{aligned}
a=2∣AB×AC∣−b+1。
以下求
b
b
b:
设斜率为
k
,
g
=
g
c
d
(
∣
x
2
−
x
1
∣
,
∣
y
2
−
y
1
∣
)
k,g=gcd(|x_2-x_1|,|y_2-y_1|)
k,g=gcd(∣x2−x1∣,∣y2−y1∣)
k
=
x
2
−
x
1
y
2
−
y
1
=
x
2
−
x
1
g
y
2
−
y
1
g
\begin{aligned}k=\frac{x_2-x_1}{y_2-y_1}=\frac{\frac{x_2-x_1}{g}}{\frac{y_2-y_1}{g}}\end{aligned}
k=y2−y1x2−x1=gy2−y1gx2−x1
直线两点式方程可变形为
x
−
x
2
=
x
1
−
x
2
y
1
−
y
2
×
(
y
−
y
1
)
\begin{aligned}{x-x_2}=\frac{x_1-x_2}{y_1-y_2}\times(y-y_1)\end{aligned}
x−x2=y1−y2x1−x2×(y−y1)
假设一点为
(
x
,
p
)
(x,p)
(x,p),其中
p
p
p为整数。
那么
x
=
x
1
−
x
2
y
1
−
y
2
×
(
p
−
y
1
)
+
x
2
=
x
2
−
x
1
g
y
2
−
y
1
g
×
(
p
−
y
2
)
+
x
2
\begin{aligned}x=\frac{x_1-x_2}{y_1-y_2}\times(p-y_1)+x_2=\frac{\frac{x_2-x_1}{g}}{\frac{y_2-y_1}{g}}\times(p-y_2)+x_2\end{aligned}
x=y1−y2x1−x2×(p−y1)+x2=gy2−y1gx2−x1×(p−y2)+x2
令
x
x
x为整数,那么
p
−
y
2
∣
y
1
−
y
2
g
\begin{aligned}p-y_2|\frac{y_1-y_2}{g}\end{aligned}
p−y2∣gy1−y2,那么可得从
x
∈
[
0
,
k
]
x\in[0, k]
x∈[0,k]满足
x
x
x为整数的个数为
k
÷
y
1
−
y
2
g
\begin{aligned}k\div\frac{y_1-y_2}{g}\end{aligned}
k÷gy1−y2。
可得一条
(
x
1
,
y
1
)
(x_1,y_1)
(x1,y1)到
(
x
2
,
y
2
)
(x_2,y_2)
(x2,y2)的线段经过的格点数为
b
1
=
y
2
÷
y
1
−
y
2
g
−
y
1
÷
y
1
−
y
2
g
+
1
=
(
y
2
−
y
1
)
×
g
y
1
−
y
2
+
1
=
g
+
1
\begin{aligned}b_1=y_2\div\frac{y_1-y_2}{g}-y_1\div\frac{y_1-y_2}{g}+1=(y_2-y_1)\times\frac{g}{y_1-y_2}+1=g+1\end{aligned}
b1=y2÷gy1−y2−y1÷gy1−y2+1=(y2−y1)×y1−y2g+1=g+1
因为顶点计算会重合,所以要减
3
3
3
所以
b
=
g
c
d
(
∣
x
2
−
x
1
∣
,
∣
y
2
−
y
1
∣
)
+
g
c
d
(
∣
x
2
−
x
3
∣
,
∣
y
2
−
y
3
∣
)
+
g
c
d
(
∣
x
3
−
x
1
∣
,
∣
y
3
−
y
1
∣
)
b=gcd(|x_2-x_1|,|y_2-y_1|)+gcd(|x_2-x_3|,|y_2-y_3|)+gcd(|x_3-x_1|,|y_3-y_1|)
b=gcd(∣x2−x1∣,∣y2−y1∣)+gcd(∣x2−x3∣,∣y2−y3∣)+gcd(∣x3−x1∣,∣y3−y1∣)
代码:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<ctype.h>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define pii pair<int,int>
#define ll long long
#define cl(x,y) memset(x,y,sizeof(x))
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define lson x<<1,l,mid
#define rson x<<1|1,mid+1,r
#define INF 1e18
const int N=1e6+10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
const double pi=acos(-1);
using namespace std;
struct point
{
double x,y;
point(){}
point(double xx,double yy){x=xx;y=yy;}
point operator +(point b){return point(x+b.x,y+b.y);}
point operator -(point b){return point(x-b.x,y-b.y);}
double operator ^(point b){return x*b.y-y*b.x;}//叉乘
double operator *(point b){return x*b.x+y*b.y;}//点乘
point operator *(double b){return point(x*b,y*b);}//数乘
double gettan(){return atan2(y,x);}//角度
void read(){scanf("%lf%lf",&x,&y);}
}a,b,c;
int f(point a,point b)
{
return __gcd(abs((int)(a.x-b.x)),abs((int)(a.y-b.y)));
}
int pick()
{
double p=f(a,b)+f(a,c)+f(b,c);
double ans=fabs(((a-b)^(a-c))/2)-p/2+1;
return (int)ans;
}
int main()
{
while(1)
{
a.read();
b.read();
c.read();
if(a.x==0 && a.y==0 && b.x==0 && b.y==0 && c.x==0 && c.y==0)
break;
printf("%d\n",pick());
}
return 0;
}