假设有如下排列
21 22 ......
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
1的坐标是(0,0), 3的坐标是(1,1),7的坐标是(-1,-1)
分析
第1层之内有1个数
第2层之内有9个数
第3层之内有25个数
则第t层之内有(2t-1)^2个数。因而第t层的数从(2t-1)^2+1开始。给定(x,y),则t=max(|x|,|y|)
分4种情况进行分析
东|右:x==t,队列增长方向与Y轴一致,正东方向(y=0)的数值为(2t-1)^2+t,因此result=(2t-1)^2+t+y
南|下:y==t,队列增长方向与X轴相反,正南方向(x=0)的数值为(2t-1)^2+3t,因此result=(2t-1)^2+3t-x
西|左:x==-t,队列增长方向与Y轴相反,正西方向(y=0)的数值为(2t-1)^2+5t,因此result=(2t-1)^2+5t-y
北|上:y==-t,队列增长方向与X轴一致,正北方向(x=0)的数值为(2t-1)^2+7t,因此result=(2t-1)^2+7t+x
Java源码如下:
import java.io.*; import java.util.StringTokenizer; public class ScrewQueue { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // TODO Auto-generated method stub int posx,posy,level; int result; while(true){ result=1; BufferedReader in =new BufferedReader(new InputStreamReader(System.in)); System.out.println("Input the position of x and y"); StringTokenizer st=new StringTokenizer(in.readLine()); posx=Integer.parseInt(st.nextToken()); posy=Integer.valueOf(st.nextToken()).intValue(); // System.out.println(posx+" "+posy); level=Math.max(Math.abs(posx),Math.abs(posy)); // System.out.println(level); if(posx==level&&posy>-level){ result=(2*level-1)*(2*level-1)+level+posy; }else if(posx<level&&posy==level){ result=(2*level-1)*(2*level-1)+3*level-posx; }else if(posx==-level&&posy<level){ result=(2*level-1)*(2*level-1)+5*level-posy; }else if(posx>-level&&posy==-level){ result=(2*level-1)*(2*level-1)+7*level+posx; } System.out.println(result); } } }
注:假设想输出一个矩阵,且i,j从0开始的话,则可以将进行坐标映射,(0,0)-->(-n/2,-n/2),然后使用上面的方法求出(m,n)的值,并且放回原来的坐标空间对应的点上即可
参考文献《程序员面试宝典》