题目描述:
蜂巢由大量的六边形拼接而成,定义蜂巢中的方向:0表示正西方向,1表示西偏北60°,2表示东偏北60°,3表示正东,4表示东偏南60°,5表示西偏南60°。对于给定一点O,以O为原点定义坐标系,如果一个点A由O点先向d方向走p步再向(d+2)mod6方向(d的顺时针120°方向)走q步到达,则这个点的坐标定义为(d,p,q)。在蜂巢中,一个点的坐标可能有多种。下图是点B(0,5,3)和点C(2,3,2)的示意图。
给定点(d1,p1,q1)和点(d2,p2,q2),请问它们之间最少走多少步可以到达?
输入格式:
输入一行,包含6个整数d1、p1、q1、d2、p2、q2,表示两个点的坐标,相邻两个整数之间使用一个空格分开。
输出格式:
输出一行,包含一个整数,表示两点之间最少走多少步可以达到。
输入样例:
0 5 3 2 3 2
输出样例:
7
思路:
将蜂巢转化为直角坐标,这样就更好看出两点间的距离。蜂室中心点坐标的距离不能直接用曼哈顿计算。
坐标之差的绝对值dx=|x1-x2|、dy=|y1-y2|,有以下结论。
1、若dx>=dy,则最少步数是(dx+dy)/2,即先横着走,再斜着走。
2、若dx<dy,一直斜着走就可以了,最少步数是dy。
比如:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
long a1[]=new long[3]; //存放点1的d、p、q
long a2[]=new long[3]; //存放点2的d、p、q
for(int i=0;i<3;i++){
a1[i]=scan.nextLong();
}
for(int i=0;i<3;i++){
a2[i]=scan.nextLong();
}
long d1=a1[0],p1=a1[1],q1=a1[2];
long[] xy1=walk(d1,p1,0,0); //按d方向走的坐标
xy1=walk((d1+2)%6,q1,xy1[0],xy1[1]);//按(d+2)%6方向走的坐标
long d2=a2[0],p2=a2[1],q2=a2[2];
long[] xy2=walk(d2,p2,0,0);
xy2=walk((d2+2)%6,q2,xy2[0],xy2[1]);
long dx=Math.abs(xy1[0]-xy2[0]);
long dy=Math.abs(xy1[1]-xy2[1]);
long ans=0;
if(dx>=dy){ //判断dx与dy大小
ans=(dx+dy)/2;
}else{ans=dy;}
System.out.println(ans);
scan.close();
}
//转化为坐标(x,y)
static long[] walk(long d,long q,long x,long y){
if(d==0){x-=2*q;}
if(d==1){x-=q;y+=q;}
if(d==2){x+=q;y+=q;}
if(d==3){x+=2*q;}
if(d==4){x+=q;y-=q;}
if(d==5){x-=q;y-=q;}
long ret[]=new long[2];
ret[0]=x;
ret[1]=y;
return ret;
}
}