reading 5螺旋队列
| 43 | 44 | 45 | 46 | 47 | 48 | 49 |
| 42 | 21 | 22 | 23 | 24 | 25 | 26 |
| 41 | 20 | 7 | 8 | 9 | 10 | 27 |
| 40 | 19 | 6 | 1 | 2 | 11 | 28 |
| 39 | 18 | 5 | 4 | 3 | 12 | 29 |
| 38 | 17 | 16 | 15 | 14 | 13 | 30 |
| 37 | 36 | 35 | 34 | 33 | 32 | 31 |
|
|
|
|
|
|
|
|
看清以上数字的排列规律,设1点的坐标是(0,0),x方向向右为正,y方向向下为正。例如,7的坐标为(-1,-1),2的坐标为(1,0),3的坐标为(1,1)。编程实现输入任意一点坐标(x,y),输出所对应的数字。
解:
tips:始终把点看成在正方形的边上,正方形的规模是变化的
给定一个坐标值(x,y)
取得|x|,|y|中的最大值为c,得出所在正方形的边长度为2c+1,正方形右上角顶点值为2c+1的平方(p),它的坐标为(m,-m)(m>=0)(作为边上点坐标的参考位置),次级正方形的右上角顶点值为2c-1的平方(q),它的坐标为(j,-j)(j>=0),y-n值的绝对值为d,x-m值的绝对值为b,判断d和b的值,
1. d= =0 && b= =0,对应的值 为p /* 右上顶点位置*/
2. d<=2c && b = =0对应的值为q+d+b; /* 右上顶点相连的竖线边长,即右边长 */
3. d= =2c&& b<=2c对应的值为q+d+b; /* 没有与右上顶点相连的横边,即下边长 */
4. d<2c && b= =2c,对应的值为p-d-b; /* 左边长,没有与右上顶点相连的竖边 */
5. d= =0 && b<2c对应的值为p-d-b; /* 上边长,与右上顶点相连的横边 */
详细源代码如下:
#include <iostream>
#include <numeric>
#include <cstdio>
using namespace std;
int max(int x, int y);
int foo(int x, int y);
int main()
{
int x,y;
for (y=-4; y<=4; y++)
{
for (x=-4; x<=4; x++)
printf("%5d", foo(x,y));
printf(" ");
}
cout << "Please input a coordinate: ";
int r;
while (cin >> x >> y)
{
r = foo (x, y);
cout << r << endl;
cout << "Pleas input a coordinate: ";
}
return 0;
}
int max(int x, int y)
{
return x > y ? x : y;
}
int foo(int x, int y)
{
//点(x,y)所在正方形的各项参数
int iMax = max(abs(x), abs(y));
int iLength = 2*iMax + 1;
int iRpValue = iLength * iLength;
int istep = (iLength-1) / 2;
int iRpX = istep;
int iRpY = 0 - istep;
//点(x,y)次级正方形的各项参数
int isRpValue = (iLength-2) * (iLength-2);
//求出(x,y)与正方形顶点的纵横坐标差值的绝对值
int iYd = abs(y - iRpY);
int iXd = abs(x - iRpX);
//根据iYd和iXd的值的分布, 得出点(x,y)相应的数
int iValue;
if (iYd==0 && iXd==0)
iValue = iRpValue;
else if ((iYd<=iLength-1 && iXd==0)
|| (iYd==iLength-1 && iXd<=iLength-1))
iValue = isRpValue + iYd + iXd;
else if ((iYd<iLength-1 && iXd==iLength-1)
|| (iYd==0 && iXd<iLength-1))
iValue = iRpValue - iYd - iXd;
else iValue = -1; /* error handling*/
return iValue;
}