蜂窝图
时间限制: 1S类别: 二维数组->较难
问题描述
在一张由无限多个大小相等的正六边形无缝拼接的无限大的地图上,所有的正六边形都有一个唯一的编号,从1开始,一圈圈往外绕。下图中我画到第30个,但其实有无穷多个,下图中空白的区域的编号我还没画,但是每个正六边形都有一个唯一的编号。
你的任务是找到绕圈的规律并补完这张图上的空白的正六边形的数字,并且写个程序回答我,如果你从其中一个正六边形走到另一个六边形,最少需要走几步。这里一“步”指的是从一个正六边形走到相邻的正六边形。所谓相邻,指的是两个正六边形有公共边。
输入说明 :
多组测试数据,最多会有5000组测试数据,所以请注意运行时间不要超时。
每组数据只有一行,包含两个整数n,m(1≤n,m≤1000)。
输出说明 :
对于每组测试数据,输出一行。一行当中只有一个数字,表示从编号n的正六边形走到编号m的正六边形所对应的最小步数。
输入范例 :
4 5
9 1
19 23
30 10
5 10
10 6
28 13
15 9
13 13
13 11
28 22
22 30
23 29
31 15
18 31
输出范例 :
1
2
3
4
3
3
1
4
0
2
6
6
5
1
4
#include <iostream>
#include <cmath>
using namespace std;
int map[1030][2];
//循环转圈的方向数组
const int dir[6][2] = {{1, -1},
{1, 1},
{0, 2},
{-1, 1},
{-1, -1},
{0, -2}};
int main() {
int n = 2, k = 0, a, b;
map[1][0] = 0;
map[1][1] = 0;
while (n <= 1000) {
for (int i = 0; i < k - 1; ++i) {
map[n][0] = map[n - 1][0] + dir[0][0];
map[n][1] = map[n - 1][1] + dir[0][1];
n++;
}
for (int i = 1; i < 5; ++i) {
for (int j = 0; j < k; ++j) {
map[n][0] = map[n - 1][0] + dir[i][0];
map[n][1] = map[n - 1][1] + dir[i][1];
n++;
}
}
for (int i = 0; i < k + 1; ++i) {
map[n][0] = map[n - 1][0] + dir[5][0];
map[n][1] = map[n - 1][1] + dir[5][1];
n++;
}
++k;
}
while (cin >> a >> b) {
int x = abs(map[a][0] - map[b][0]);
int y = abs(map[a][1] - map[b][1]);
if (x >= y)
cout << x << endl;
else{
cout << x + (y - x) / 2 << endl;
}
}
return 0;
}