poj1870

题意:给定一个蜂窝,按如图规则给每个六边形孔顺时针绕圈标号,问某两个标号之间的距离。

分析:把每个六边形看作正方形,并建立平面直角坐标系。1号位于(0,0)。x轴从左上到右下方向,y轴从左下到右上方向。然后将图转化为正方形的图。对于一个给定的编号利用公式计算是第几圈的,再算是6条边中哪条边的,再计算坐标。两个点之间的行走规则是,先将图看作正方形组成,可走正方形横竖相邻的正方形,也可走其捺对角线,但不能走其撇对角线。

View Code
#include <iostream>
#include
<cstdio>
#include
<cstdlib>
#include
<cstring>
#include
<cmath>
using namespace std;

struct Point
{
int x, y;
};

int a, b;

Point cal(
int a)
{
Point ret;
if (a == 1)
{
ret.x
= 0;
ret.y
= 0;
return ret;
}
int n = sqrt((a - 1) / 3);
while (3 * (n - 1) * n + 1 < a)
n
++;
while (3 * (n - 1) * n + 1 >= a)
n
--;
a
-= 3 * (n - 1) * n + 1;
if (a <= n)
{
ret.x
= n;
ret.y
= -a;
}
else if (a > n && a <= 2 * n)
{
ret.x
= n - a + n;
ret.y
= -n;
}
else if (a > 2 * n && a <= 3 * n)
{
ret.x
= 2 * n - a;
ret.y
= -n - ret.x;
}
else if (a > 3 * n && a <= 4 * n)
{
ret.x
= -n;
ret.y
= a - 3 * n;
}
else if (a > 4 * n && a <= 5 * n)
{
ret.x
= (a - 4 * n) - n;
ret.y
= n;
}
else
{
ret.x
= a - 5 * n;
ret.y
= n - ret.x;
}
return ret;
}

int main()
{
//freopen("t.txt", "r", stdin);
while (scanf("%d%d", &a, &b), a | b)
{
Point p
= cal(a);
Point q
= cal(b);
Point ans;
ans.x
= p.x - q.x;
ans.y
= p.y - q.y;
int temp;
if (ans.x * ans.y <= 0)
temp
= max(abs(ans.x), abs(ans.y));
else
temp
= abs(ans.x + ans.y);
printf(
"The distance between cells %d and %d is %d.\n", a, b, temp);
}
return 0;
}
原文地址:https://www.cnblogs.com/rainydays/p/2139974.html