社会我赞哥
说在前面
今天,也就是公元2019年6月28日,时隔两个月,多才多艺的yuzan1830又给本蒟蒻出新题了。(篇幅略长,慎入。)
他先在纸上画了一个半径为
1
1
1的圆,圆心标为
A
1
A_1
A1。
然后他在
⊙
A
1
\odot A_1
⊙A1上继续以
1
1
1为半径接连作了六个圆,依次标为
B
1
,
B
2
,
…
,
B
6
B_1,B_2,\dots,B_6
B1,B2,…,B6。
他发现
B
B
B这一层的圆出现了新的交点。于是他以这些交点为圆心继续画圆。
他发现
C
C
C这一层的圆又出现了新的交点。于是他以这些交点为圆心继续画圆。
达羌:。。。你们自己理解就行了,我不画了!
直到某个时刻,他发现自己的纸已经画不下这么多圆了。
但他想象自己能从
A
A
A一直画到
Z
Z
Z,甚至,从
A
1
A_1
A1开始向外画
10000
10000
10000层。
现在yuzan1830画了
n
n
n层圆(不包括
A
1
A_1
A1)。然后他每次给出形如
N
a
,
M
b
N_a,M_b
Na,Mb的两个点,问射线
N
a
M
b
N_aM_b
NaMb一共经过了纸上的多少个点。
例如
n
=
2
n=2
n=2,射线
C
1
B
1
C_1B_1
C1B1经过了
C
1
,
B
1
,
A
1
,
B
4
,
C
7
C_1,B_1,A_1,B_4,C_7
C1,B1,A1,B4,C7五个点;
n
=
3
n=3
n=3,射线
D
1
B
2
D_1B_2
D1B2经过了
D
1
,
B
2
,
D
8
D_1,B_2,D_8
D1,B2,D8三个点。
接受挑战
在yuzan1830的指引下,本蒟蒻勉强能够领会图中形成的规整的六边形的美。但是六边形太难了,本人思考了一下正方形的情况。
这么多点当然建系最优秀了。
达羌:。。。正方形还是比较好画的。
问题来了,为什么要把这个正方形斜过来?
因为这样的话属于同一层的点到原点的曼哈顿距离相等,便于点的名称和坐标之间的对应。
假设已知两点的坐标
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
(x_1,y_1),(x_2,y_2)
(x1,y1),(x2,y2),以图中
D
1
(
0
,
3
)
,
D
5
(
2
,
−
1
)
D_1(0,3),D_5(2,-1)
D1(0,3),D5(2,−1)为例。
下面考虑求以这两点为端点的线段上的点的个数。
很明显这条线段上的点是等距的,则点的个数
=
=
=线段长度
÷
\div
÷相邻两点间的距离(下文简称为邻接距离)
+
1
+1
+1。
如上图,
D
1
,
D
5
D_1,D_5
D1,D5的距离可表示为
Δ
x
+
Δ
y
=
2
+
4
\Delta x+\Delta y=2+4
Δx+Δy=2+4。保持斜率
k
=
Δ
y
Δ
x
=
4
2
k=\frac{\Delta y}{\Delta x}=\frac 42
k=ΔxΔy=24不变,将
Δ
x
,
Δ
y
\Delta x,\Delta y
Δx,Δy同时减半,得到一个更短的距离
1
+
2
1+2
1+2。这个距离实际上就是
D
1
,
C
2
D_1,C_2
D1,C2或
C
2
,
D
5
C_2,D_5
C2,D5的距离。
由于点的坐标全部是整数,故可以将
Δ
x
,
Δ
y
\Delta x,\Delta y
Δx,Δy等比例缩小,当
g
c
d
(
Δ
x
,
Δ
y
)
=
1
gcd(\Delta x,\Delta y)=1
gcd(Δx,Δy)=1时,得到的距离
Δ
x
+
Δ
y
\Delta x+\Delta y
Δx+Δy即为邻接距离。
问题来了,这个距离求的是线段上的点。求射线上的点怎么办?
延长线段就好了。只需求出终点的位置。可以根据
{
∣
x
∣
+
y
⩽
n
∣
x
∣
−
y
⩽
n
\begin{cases}|x|+y\leqslant n\\|x|-y\leqslant n\end{cases}
{∣x∣+y⩽n∣x∣−y⩽n来计算。
最后一个问题,人家给的是
N
a
,
M
b
N_a,M_b
Na,Mb,怎么把它转换成坐标?
不妨设
N
a
N_a
Na在第
n
0
n_0
n0层,则坐标
(
x
,
y
)
(x,y)
(x,y)一定满足
∣
x
∣
+
∣
y
∣
=
n
0
|x|+|y|=n_0
∣x∣+∣y∣=n0。
考虑
y
y
y轴正半轴与第一象限组成的区域,通过观察不难发现这个区域中第
n
0
n_0
n0层的点包括
N
1
,
N
2
,
…
,
N
n
0
N_1,N_2,\dots,N_{n_0}
N1,N2,…,Nn0,且横坐标顺时针递增。
同理,
x
x
x轴正半轴与第四象限组成的区域中的点包括
N
n
0
+
1
,
N
n
0
+
2
,
⋯
 
,
N
2
n
0
N_{n_0+1},N_{n_0+2},\cdots,N_{2n_0}
Nn0+1,Nn0+2,⋯,N2n0,且横坐标顺时针递减。
y
y
y轴负半轴与第三象限组成的区域中的点包括
N
2
n
0
+
1
,
N
2
n
0
+
2
,
⋯
 
,
N
3
n
0
N_{2n_0+1},N_{2n_0+2},\cdots,N_{3n_0}
N2n0+1,N2n0+2,⋯,N3n0,且横坐标顺时针递减。
x
x
x轴负半轴与第二象限组成的区域中的点包括
N
3
n
0
+
1
,
N
3
n
0
+
2
,
⋯
 
,
N
4
n
0
N_{3n_0+1},N_{3n_0+2},\cdots,N_{4n_0}
N3n0+1,N3n0+2,⋯,N4n0,且横坐标顺时针递增。
于是通过推算得出结论:
N
a
{
(
a
−
1
,
n
0
−
a
+
1
)
0
<
a
⩽
n
0
(
2
n
0
−
a
+
1
,
n
0
−
a
+
1
)
n
0
<
a
⩽
2
n
0
(
2
n
0
−
a
+
1
,
−
3
n
0
+
a
−
1
)
2
n
0
<
a
⩽
3
n
0
(
−
4
n
0
+
a
−
1
,
−
3
n
0
+
a
−
1
)
3
n
0
<
a
⩽
4
n
0
N_a\begin{cases} (a-1,n_0-a+1)&0<a\leqslant n_0\\ (2n_0-a+1,n_0-a+1)&n_0<a\leqslant 2n_0\\ (2n_0-a+1,-3n_0+a-1)&2n_0<a\leqslant 3n_0\\ (-4n_0+a-1,-3n_0+a-1)&3n_0<a\leqslant 4n_0 \end{cases}
Na⎩⎪⎪⎪⎨⎪⎪⎪⎧(a−1,n0−a+1)(2n0−a+1,n0−a+1)(2n0−a+1,−3n0+a−1)(−4n0+a−1,−3n0+a−1)0<a⩽n0n0<a⩽2n02n0<a⩽3n03n0<a⩽4n0
至此,问题就解决了。
每次询问的时间复杂度为
O
(
log
2
n
)
O(\log_2 n)
O(log2n),因为求单位距离时用到了
g
c
d
gcd
gcd,而其他部分的时间复杂度均为常数。
更多挑战
然而,问题真的解决了吗?
回到yuzan1830画的那张图:
看似美妙的正六边形,
达羌:。。。一点都不好玩。
因为有了许多
60
°
60\degree
60°,怎样建系都成了一个问题。极坐标系难以表示距离,笛卡尔坐标系又会算出一堆根式。yuzan1830不愧是神犇,甚至尝试用纯几何方法解决这个问题。
经过比较探讨,我们决定:暴力建系!
建出来就是这么丑,但是,没得法的鸭!
系建好了,然后依次解决之前的问题:
求坐标
yuzan1830:既然坐标系已经这么丑了,为什么不能再暴力一点!
我们以
A
1
B
1
A_1B_1
A1B1为基准线。对于点
N
a
N_a
Na,先找到
N
1
N_1
N1,然后绕原点顺时针旋转。先将
a
a
a转掉
n
n
n的整数倍,每一次转
60
°
60\degree
60°;对于剩余的
a
m
o
d
  
n
a\mod n
amodn计算出还需转动的角度和最终
N
a
N_a
Na与原点的距离。时间复杂度为常数。
以上图的
C
4
C_4
C4为例,首先不难得到
∣
C
1
A
1
∣
=
2
|C_1A_1|=2
∣C1A1∣=2,旋转角为
120
°
120\degree
120°。然后顺时针旋转
60
°
60\degree
60°到
C
3
C_3
C3位置,这样能保证到原点的距离不变。然后在
△
A
1
C
3
C
4
\triangle A_1C_3C_4
△A1C3C4中解三角形,得到
∣
A
1
C
4
∣
=
3
|A_1C_4|=\sqrt3
∣A1C4∣=3,旋转角为
30
°
30\degree
30°,进而求出
C
4
(
3
2
,
3
2
)
C_4(\frac 32,\frac{\sqrt3}2)
C4(23,23)。
一般地,设
N
a
N_a
Na位于第
n
0
n_0
n0层(
n
0
>
0
n_0>0
n0>0),则
∣
N
1
A
1
∣
=
n
0
|N_1A_1|=n_0
∣N1A1∣=n0,旋转角永远为
120
°
120\degree
120°。
N
a
N_a
Na到原点的距离
∣
N
a
A
1
∣
=
n
0
2
+
(
a
−
1
m
o
d
  
n
0
)
2
−
2
n
0
(
a
−
1
m
o
d
  
n
0
)
cos
60
°
=
r
|N_aA_1|=\sqrt{n_0^2+(a-1\mod n_0)^2-2n_0(a-1\mod n_0)\cos 60\degree}=r
∣NaA1∣=n02+(a−1modn0)2−2n0(a−1modn0)cos60°=r
N a N_a Na从 N 1 N_1 N1需旋转的角度 ∠ N 1 A 1 N a = ⌊ a − 1 n 0 ⌋ ⋅ 60 ° + arccos n 0 − ( a − 1 m o d    n 0 ) cos 60 ° n 0 2 + ( a − 1 m o d    n 0 ) 2 − 2 n 0 ( a − 1 m o d    n 0 ) cos 60 ° = θ \angle N_1A_1N_a=\lfloor\frac{a-1}{n_0}\rfloor\cdot 60\degree+\arccos\frac{n_0-(a-1\mod n_0)\cos 60\degree}{\sqrt{n_0^2+(a-1\mod n_0)^2-2n_0(a-1\mod n_0)\cos 60\degree}}=\theta ∠N1A1Na=⌊n0a−1⌋⋅60°+arccosn02+(a−1modn0)2−2n0(a−1modn0)cos60°n0−(a−1modn0)cos60°=θ
于是点
N
a
N_a
Na的坐标就出来了,很简单对不对?
N
a
(
r
cos
(
120
°
−
θ
)
,
r
sin
(
120
°
−
θ
)
)
N_a(r\cos(120\degree-\theta),r\sin(120\degree-\theta))
Na(rcos(120°−θ),rsin(120°−θ))
延长线段
跟正四边形的情况类似,即将给定线段从终点开始向外延伸邻接距离的整数倍,使之达到最长而又不越过第
n
n
n层(第
n
n
n层外面已经没有点了)。延长线段是用来求总距离的,故邻接距离可以在此之前计算好。
n
n
n层点中所有点的坐标一定满足以下条件:
{
∣
x
tan
60
°
−
y
∣
⩽
n
tan
60
°
∣
x
tan
60
°
+
y
∣
⩽
n
tan
60
°
∣
y
∣
⩽
n
sin
60
°
\begin{cases} |x\tan 60\degree-y|\leqslant n\tan 60\degree\\ |x\tan 60\degree+y|\leqslant n\tan 60\degree\\ |y|\leqslant n\sin 60\degree \end{cases}
⎩⎪⎨⎪⎧∣xtan60°−y∣⩽ntan60°∣xtan60°+y∣⩽ntan60°∣y∣⩽nsin60°
这个比较显然,其实就是第
n
n
n层的点所在的六条直线的方程。
给定线段有起点
N
a
(
x
1
,
y
1
)
N_a(x_1,y_1)
Na(x1,y1)和终点
M
b
(
x
2
,
y
2
)
M_b(x_2,y_2)
Mb(x2,y2),不妨把它看成一个向量
N
a
M
b
→
=
(
x
2
−
x
1
,
y
2
−
y
1
)
=
r
⃗
\overrightarrow{N_aM_b}=(x_2-x_1,y_2-y_1)=\vec r
NaMb=(x2−x1,y2−y1)=r,用坐标表示。
从该向量上截取一段与邻接距离等长的向量
d
⃗
\vec d
d(下文记为邻接向量)。要延长线段,就在原向量上加
d
⃗
\vec d
d就行了。
设给定线段向外延伸了
k
k
k个邻接距离,那么延伸后的终点
(
x
2
+
k
x
d
⃗
,
y
2
+
k
y
d
⃗
)
(x_2+kx_{\vec d},y_2+ky_{\vec d})
(x2+kxd,y2+kyd)一定落在六边形的范围内,即满足上述不等式组。解出最大的
k
k
k即可。
求距离
整条线段的距离直接套距离公式就可以了。关键是如何求邻接距离。
回想一下,图形为正方形时,我们把两点的距离分成了
Δ
x
,
Δ
y
\Delta x,\Delta y
Δx,Δy,然后对
Δ
x
,
Δ
y
\Delta x,\Delta y
Δx,Δy进行“约分”。但是现在,六边形放在直角坐标系中显得不伦不类。
我们考虑两个单位向量
e
⃗
1
=
(
1
,
0
)
,
e
⃗
2
=
(
cos
60
°
,
sin
60
°
)
\vec e_1=(1,0),\vec e_2=(\cos 60\degree,\sin 60\degree)
e1=(1,0),e2=(cos60°,sin60°),与
x
x
x轴正方向夹角分别为
0
°
,
60
°
0\degree,60\degree
0°,60°,作为基底。根据平面向量基本定理,原向量
r
⃗
\vec r
r可以基于
e
⃗
1
,
e
⃗
2
\vec e_1,\vec e_2
e1,e2,用另一整数对
(
p
,
q
)
(p,q)
(p,q)来表示。
于是可以列出关于
p
,
q
p,q
p,q的方程:
p
e
⃗
1
+
q
e
⃗
2
=
r
⃗
p\vec e_1+q\vec e_2=\vec r
pe1+qe2=r
即
{
p
+
q
cos
60
°
=
x
2
−
x
1
q
sin
60
°
=
y
2
−
y
1
\begin{cases} p+q\cos 60\degree=x_2-x_1\\ q\sin 60\degree=y_2-y_1 \end{cases}
{p+qcos60°=x2−x1qsin60°=y2−y1
解得
p
=
x
2
−
x
1
−
y
2
−
y
1
tan
60
°
,
q
=
y
2
−
y
1
sin
60
°
p=x_2-x_1-\frac{y_2-y_1}{\tan 60\degree},q=\frac{y_2-y_1}{\sin 60\degree}
p=x2−x1−tan60°y2−y1,q=sin60°y2−y1
然后仿照图形为四边形的做法,将
p
,
q
p,q
p,q等比例缩小直至互质,求出邻接向量
d
⃗
=
p
g
c
d
(
p
,
q
)
e
⃗
1
+
q
g
c
d
(
p
,
q
)
e
⃗
2
=
r
⃗
g
c
d
(
p
,
q
)
\vec d=\frac p{gcd(p,q)}\vec e_1+\frac q{gcd(p,q)}\vec e_2=\frac{\vec r}{gcd(p,q)}
d=gcd(p,q)pe1+gcd(p,q)qe2=gcd(p,q)r
而邻接距离就是邻接向量的模长。
计算
同上。
a
n
s
=
∣
r
⃗
+
k
d
⃗
∣
∣
d
⃗
∣
+
1
=
g
c
d
(
p
,
q
)
+
k
+
1
ans=\frac{|\vec r+k\vec d|}{|\vec d|}+1=gcd(p,q)+k+1
ans=∣d∣∣r+kd∣+1=gcd(p,q)+k+1
每次询问的时间复杂度依旧为 O ( log 2 n ) O(\log_2 n) O(log2n)。
说在后面
其实正六边形的情况已经具有普遍性了。只需改变一下旋转角,理论上可以普及到任意正多边形。不过实现起来没有正六边形这么方便。果然正六边形还是最美的啊。
值得一提的是,前面正四边形的做法虽然有些投机取巧,但是整个计算过程中没有涉及浮点数。
yuzan1830正等待着本蒟蒻写出代码。他太天真了!
继续说在后面
2019年7月12日
后来还是花了点时间捣鼓出来了两段代码。
由于原题是正六边形,本人在处理正四边形的情况的时候只保证理论可行,而并没有仔细去考虑如何实现,毕竟问题的重心在正六边形的情况上。这导致一些具体过程在正六边形的情况中才得以铺开。关于正四边形的具体实现可以参考下面的代码。
另外正四边形的做法不涉及浮点数的说法也不准确,因为延长线段要解不等式。虽然可以用整除代替,但实现起来太麻烦。
说明一下输入格式:
第一行为一个整数
n
n
n,表示在
A
1
A_1
A1的基础上向外画了
n
n
n层圆。由于层数可达到
10000
10000
10000,无法用字母表示,故用数字表示层数,
A
1
A_1
A1位于第
0
0
0层,
B
1
B_1
B1位于第
1
1
1层,以此类推。
接下来若干行,每行中n1-a1 to n2-b2
表示询问射线
P
Q
PQ
PQ经过的点的个数,其中
P
P
P是第
n
1
n_1
n1层第
a
1
a_1
a1个点,
Q
Q
Q是第
n
2
n_2
n2层第
a
2
a_2
a2个点。输入保证合法。
正四边形
样例输入
3
3-1 to 3-5
3-1 to 2-2
2-7 to 2-4
1-3 to 1-1
样例输出
3
3
2
5
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int INF=0x7fffffff;
const double EPS=1e-6;
// point: 坐标系中的点
struct point{
int x,y;
point(int x=0,int y=0):x(x),y(y){}
// dist(a,b): 点a,b的曼哈顿距离
friend int dist(point a,point b){
return abs(a.x-b.x)+abs(a.y-b.y);
}
// convec(p1,p2): 与p1p2共线的邻接向量
friend point convec(point p1,point p2){
int dx=p2.x-p1.x,dy=p2.y-p1.y,gcd=__gcd(abs(dx),abs(dy));
return point(dx/gcd,dy/gcd);
}
};
// coord(n0,a): 第n0层第a个点的坐标
// coord(n0,a) = (a-1,n0-a+1) 0<a<=n0
// coord(n0,a) = (2n0-a+1,n0-a+1) n0<a<=2n0
// coord(n0,a) = (2n0-a+1,-3n0+a-1) 2n0<a<=3n0
// coord(n0,a) = (-4n0+a-1,-3n0+a-1) 3n0<a<=4n0
point coord(int n0,int a){
if(!n0)return point(0,0);
if(a<=n0)return point(a-1,n0-a+1);
if(a<=2*n0)return point(2*n0-a+1,n0-a+1);
if(a<=3*n0)return point(2*n0-a+1,-3*n0+a-1);
return point(-4*n0+a-1,-3*n0+a-1);
}
// extend(p1,p2,n): 延长p1p2使之不超过第n层,返回cnt
// d = convec(p1,p2)
// |p2.x+cnt*d.x|+(p2.y+cnt*d.y) <= n
// |p2.x+cnt*d.x|-(p2.y+cnt*d.y) <= n
int extend(point p1,point p2,int n){
point d=convec(p1,p2);
double t1=INF,b1=-INF,t2=INF,b2=-INF;
int cnt=INF;
if(d.x+d.y){
t1=(double)(n-p2.x-p2.y)/(d.x+d.y);
b1=(double)(-n-p2.x-p2.y)/(d.x+d.y);
}
if(d.x-d.y){
t2=(double)(n-p2.x+p2.y)/(d.x-d.y);
b2=(double)(-n-p2.x+p2.y)/(d.x-d.y);
}
if(d.x+d.y<0)swap(b1,t1);
if(d.x-d.y<0)swap(b2,t2);
if(b1-EPS<t1)cnt=min(cnt,(int)floor(t1+EPS));
if(b2-EPS<t2)cnt=min(cnt,(int)floor(t2+EPS));
return max(cnt,0);
}
// ans = gcd(p1p2.x,p1p2.y)+cnt+1
int main(){
int n,n1,a1,n2,a2;
scanf("%d",&n);
while(scanf("%d-%d to %d-%d",&n1,&a1,&n2,&a2)==4){
point p1=coord(n1,a1),p2=coord(n2,a2);
printf("%d\n",__gcd(abs(p1.x-p2.x),abs(p1.y-p2.y))+extend(p1,p2,n)+1);
}
return 0;
}
正六边形
样例输入
3
3-1 to 1-2
0-1 to 2-5
2-2 to 2-3
样例输出
3
4
3
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int INF=0x7fffffff;
const double EPS=1e-6;
const double PI=acos(-1);
const double sin60=sin(PI/3);
const double cos60=cos(PI/3);
const double tan60=tan(PI/3);
// double_to_int: 万恶的浮点数误差
int double_to_int(double x){
if(x>0)x+=EPS;else x-=EPS;
return (int)x;
}
// point: 坐标系中的点
struct point{
double x,y;
point(double x=0,double y=0):x(x),y(y){}
// dist(a,b): 点a,b的欧几里得距离
friend double dist(point a,point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
// convec(p1,p2): 与p1p2同向的邻接向量
// p+q*cos60 = p2.x-p1.x
// q*sin60 = p2.y-p1.y
// d = (p2-p1)/gcd(p,q)
friend point convec(point p1,point p2){
int p=double_to_int(p2.x-p1.x-(p2.y-p1.y)/tan60);
int q=double_to_int((p2.y-p1.y)/sin60);
int gcd=__gcd(abs(p),abs(q));
return point((p2.x-p1.x)/gcd,(p2.y-p1.y)/gcd);
}
};
// coord(n0,a): 第n0层第a个点的坐标
// r^2 = n0^2+(a-1 mod n0)^2-2*n0(a-1 mod n)cos60
// theta = [(a-1)/n0](PI/3)+acos((n0-(a-1 mod n0)cos60)/r)
// coord(n0,a) = (r*cos(PI*2/3-theta),r*sin(PI*2/3-theta))
point coord(int n0,int a){
if(!n0)return point(0,0);
int left=(a-1)%n0;
double r=sqrt(n0*n0+left*left-2*n0*left*cos60);
double theta=floor((a-1)/n0)*(PI/3)+acos((n0-left*cos60)/r);
return point(r*cos(PI*2/3-theta),r*sin(PI*2/3-theta));
}
// extend(p1,p2,n): 延长p1p2使之不超过第n层,返回cnt
// d = convec(p1,p2)
// |(p2.x+cnt*d.x)tan60-(p2.y+cnt*d.y)| <= n*tan60
// |(p2.x+cnt*d.x)tan60+(p2.y+cnt*d.y)| <= n*tan60
// |p2.y+cnt*d.y| <= n*sin60
int extend(point p1,point p2,int n){
point d=convec(p1,p2);
double t1=INF,b1=-INF,t2=INF,b2=-INF,t3=INF,b3=-INF;
int cnt=INF;
if(fabs(d.x*tan60-d.y)>EPS){
t1=(n*tan60-p2.x*tan60+p2.y)/(d.x*tan60-d.y);
b1=(-n*tan60-p2.x*tan60+p2.y)/(d.x*tan60-d.y);
}
if(fabs(d.x*tan60+d.y)>EPS){
t2=(n*tan60-p2.x*tan60-p2.y)/(d.x*tan60+d.y);
b2=(-n*tan60-p2.x*tan60-p2.y)/(d.x*tan60+d.y);
}
if(fabs(d.y)>EPS){
t3=(n*sin60-p2.y)/d.y;
b3=(-n*sin60-p2.y)/d.y;
}
if(d.x*tan60-d.y<-EPS)swap(b1,t1);
if(d.x*tan60+d.y<-EPS)swap(b2,t2);
if(d.y<-EPS)swap(t3,b3);
if(b1-EPS<t1)cnt=min(cnt,(int)floor(t1+EPS));
if(b2-EPS<t2)cnt=min(cnt,(int)floor(t2+EPS));
if(b3-EPS<t3)cnt=min(cnt,(int)floor(t3+EPS));
return max(cnt,0);
}
// ans = gcd(p,q)+cnt+1
int main(){
int n,n1,a1,n2,a2;
scanf("%d",&n);
while(scanf("%d-%d to %d-%d",&n1,&a1,&n2,&a2)==4){
point p1=coord(n1,a1),p2=coord(n2,a2);
int p=double_to_int(p2.x-p1.x-(p2.y-p1.y)/tan60+EPS);
int q=double_to_int((p2.y-p1.y)/sin60+EPS);
printf("%d\n",__gcd(abs(p),abs(q))+extend(p1,p2,n)+1);
}
return 0;
}
完。