来自yuzan1830的挑战(二)

社会我赞哥

说在前面

今天,也就是公元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+ynxyn来计算。

最后一个问题,人家给的是 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 &lt; a ⩽ n 0 ( 2 n 0 − a + 1 , n 0 − a + 1 ) n 0 &lt; a ⩽ 2 n 0 ( 2 n 0 − a + 1 , − 3 n 0 + a − 1 ) 2 n 0 &lt; a ⩽ 3 n 0 ( − 4 n 0 + a − 1 , − 3 n 0 + a − 1 ) 3 n 0 &lt; a ⩽ 4 n 0 N_a\begin{cases} (a-1,n_0-a+1)&amp;0&lt;a\leqslant n_0\\ (2n_0-a+1,n_0-a+1)&amp;n_0&lt;a\leqslant 2n_0\\ (2n_0-a+1,-3n_0+a-1)&amp;2n_0&lt;a\leqslant 3n_0\\ (-4n_0+a-1,-3n_0+a-1)&amp;3n_0&lt;a\leqslant 4n_0 \end{cases} Na(a1,n0a+1)(2n0a+1,n0a+1)(2n0a+1,3n0+a1)(4n0+a1,3n0+a1)0<an0n0<a2n02n0<a3n03n0<a4n0

至此,问题就解决了。
每次询问的时间复杂度为 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 &ThinSpace;&ThinSpace; 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 &gt; 0 n_0&gt;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 &ThinSpace;&ThinSpace; n 0 ) 2 − 2 n 0 ( a − 1 m o d &ThinSpace;&ThinSpace; 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+(a1modn0)22n0(a1modn0)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 &ThinSpace;&ThinSpace; n 0 ) cos ⁡ 60 ° n 0 2 + ( a − 1 m o d &ThinSpace;&ThinSpace; n 0 ) 2 − 2 n 0 ( a − 1 m o d &ThinSpace;&ThinSpace; 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=n0a160°+arccosn02+(a1modn0)22n0(a1modn0)cos60° n0(a1modn0)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°yntan60°xtan60°+yntan60°ynsin60°

这个比较显然,其实就是第 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 =(x2x1,y2y1)=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) e 1=(1,0),e 2=(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 e 1,e 2,用另一整数对 ( 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 pe 1+qe 2=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°=x2x1qsin60°=y2y1

解得
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=x2x1tan60°y2y1,q=sin60°y2y1

然后仿照图形为四边形的做法,将 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)pe 1+gcd(p,q)qe 2=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;
}

完。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值