题目链接:点击打开链接
题目大意:给出一个蜂窝,也就是有六边形组成,从内向外不断的循环(如图),给出两个数的值u,v按六边形的走法,由中心向六个角走。问由u到v的的最小步数。
首先处理处每一个数的坐标,让1点位(0,0)其他的点预先处理出来。
然后计算两个数的距离时,我们可以计算两个数的位置横坐标差位x,纵坐标差位y,当x < y的时候,按照斜线走,走到相同列的时候就可以直接向下走,一直到v,在向下走的时候,一步可以走坐标中的2的距离。
当x>=y的时候,可以先斜线走走到相同的行,然后横正走,一直找到v,在横着走的时候,一次只能走一个坐标。
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std ; struct point{ int x , y ; }p , q , a[10010] ; int s[6][2] = { {-1,-1},{-1,1},{0,2},{1,1},{1,-1},{0,-2} } ; void init() { a[1].x = a[1].y = 0 ; int k , i , j , cnt = 1 ; for(k = 2 ; cnt < 10000 ; k++) { p.x = a[cnt].x ; p.y = a[cnt].y-2 ; a[++cnt] = p ; for(i = 0 ; i < 6 ; i++) { for(j = 0 ; j < k-1 ; j++) { if( i == 0 && j == k-2 ) continue ; p.x += s[i][0] ; p.y += s[i][1] ; a[++cnt] = p ; if( cnt == 10000 ) break ; } if( cnt == 10000 ) break ; } } } int main() { init() ; int u , v , x , y , ans ; while( scanf("%d %d", &u, &v) && u+v ) { x = abs(a[u].x-a[v].x) ; y = abs(a[u].y-a[v].y) ; ans = 0 ; if( x < y ) { ans = x + (y-x)/2 ; } else ans = y + (x-y) ; printf("The distance between cells %d and %d is %d.\n", u, v, ans ) ; } return 0 ; }