本题我用的方法是模拟.
#include <iostream>
#include <math.h>
inline int GetLine(int m)
{
double sqrtm = sqrt((long double)m);
if ((sqrtm - (int)sqrtm) > 0)
{
return (int)sqrtm + 1;
}
else
{
return (int)sqrtm;
}
}
inline bool UpInLine(int m)
{
// Get line number of m
int line = GetLine(m);
if (line % 2 != 0)
{
// if line is odd, odd down, even up
return (m % 2 == 0) ? true : false;
}
else
{
// if line is even, odd up, even down
return (m % 2 == 0) ? false : true;
}
}
inline bool SameLine(int m, int n)
{
return GetLine(m) == GetLine(n);
}
// is m is left to n
inline bool DirectLeft(int m, int n)
{
// Move m to the line same as n
int linem = GetLine(m);
int linen = GetLine(n);
int movem = m;
while (linem < linen)
{
movem += 2 * linem;
linem++;
}
return (movem < n) ? true : false;
}
inline int MoveDown(int m)
{
return m + 2 * GetLine(m);
}
inline int MoveLeft(int m)
{
return m - 1;
}
inline int MoveRight(int m)
{
return m + 1;
}
int main()
{
int m, n;
while (std::cin >> m >> n)
{
// let m < n
if (m > n)
{
int tmp = m;
m = n;
n = tmp;
}
int count = 0;
// up to down
while (m != n)
{
if (GetLine(m) != GetLine(n))
{
// if m, n is not in the same line
if (UpInLine(m))
{
// if m is up in its line, move left or right, by it's direct to n
if (DirectLeft(m, n))
{
// Move Right
m = MoveRight(m);
}
else
{
m = MoveLeft(m);
}
}
else
{
// if m is down in its line, move down
m = MoveDown(m);
}
}
else
{
// if m, n is in the same line
// direct move m left or right by it's direct to n
if (DirectLeft(m, n))
{
m = MoveRight(m);
}
else
{
m = MoveLeft(m);
}
}
count++;
}
printf("%d\n", count);
}
return 0;
}