传送门:51nod 1650
思路:
满足以下条件的点为沼泽,其他地方不是沼泽:
1. |x+y|≡0 mod (2∗a)
2. |x−y|≡0 mod (2∗b)
以 a=b=2 为例,在坐标系上画出上图,我们发现有两组直线,每组直线的斜率相同,但是偏移量不同。偏移量恰好是 n 倍的 2a 和 m 倍的 2b。
所以,我们可以把最开始的两个等式改写为:
1. x+y = n * (2*a)
2. y-x = m * (2*b)
得到这个有什么用呢?我们发现两个点(如上图的绿点)一定处于两个矩形内。那么经过的沼泽数是不是就是上图中两个矩形框蓝色线相差的条数 + 红色线相差的条数呢?然鹅,并不是这样……按照这种思路过不了第 3 组测试样例。
上图是根据第 3 组测试样例所做的图,两个红色点是起始点和目的点,绿点是经过的点。我们发现它只经过了 2 个沼泽而不是 3 个,因为它经过了一个蓝色线和红色线相交的点…… 所以答案就是蓝色线相差的条数和红色线相差的条数的最大值。
相差的条数可以根据前面给出的公式求出 n 和 m,然后向上(或向下)取整后相减得到。
代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
int main()
{
int ans;
double a,b,x1,x2,y1,y2;
double u,v,x,y;
while(~scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&x1,&y1,&x2,&y2))
{
u=(x1+y1)/(2*a);
u=floor(u);
v=(x2+y2)/(2*a);
v=floor(v);
x=(y1-x1)/(2*b);
x=floor(x);
y=(y2-x2)/(2*b);
y=floor(y);
if(abs(u-v)>abs(x-y)) ans=abs(u-v); //取最大值
else ans=abs(x-y);
printf("%d\n",ans);
}
return 0;
}