看清以下数字排列的规律,设1点的坐标是(0,0),x方向向右为正,y方向向下为正。例如,7的坐标为(-1,-1),2的坐标为(0,1),3的坐标为(1,1)。编程实现输入任意一点坐标(x,y),输出所对应的数字。
21 22 23 24 25 20 7 8 9 10 19 6 1 2 11 18 5 4 3 12 17 16 15 14 13
解析:从数字排列可以得到如下规律,以1为中心点,数字有规律地一层一层往外扩展。第0层为1,第1层为2~9,第2层为10~25......
第n层的最后一个数是(2*n+1)2
所以解题关键可分为几步,先获取层数n,然后根据坐标算出与当层最后一个数的相对位置即可。
具体函数实现如下:
int fun(int x,int y) { int layer=max(abs(x),abs(y)); //计算出该坐标属于哪一层 int base=2*layer+1; int key; if(y==-layer) //上边的一行 key=base*base+y+x; else if(y==layer) //下面的一行 key=base*base-2*base+2-(y+x); else if(x==-layer && abs(y)!=layer) //左边的一行 key=base*base-base+1-(-x+y); else if(x==layer && abs(y)!=layer) //右边的一行 key=base*base-3*base+3-(x-y); else { printf("error"); return -1; } return key; }
从函数可以看出,一层有四个边,要分别讨论不同的情况。不要想用一条公式就把所有规律都表示出来。
测试代码可用如下:
#include <stdio.h> #define abs(a) ((a)>0?(a):-(a)) #define max(x,y) ((abs(x))>abs(y)?(abs(x)):(abs(y))) int fun(int x,int y) { int layer=max(abs(x),abs(y)); int base=2*layer+1; int key; if(y==-layer) key=base*base+y+x; else if(y==layer) key=base*base-2*base+2-(y+x); else if(x==-layer && abs(y)!=layer) key=base*base-base+1-(-x+y); else if(x==layer && abs(y)!=layer) key=base*base-3*base+3-(x-y); else { printf("error"); return -1; } return key; } int main(void) { int x,y; int range=4; for(y=-range;y<=range;y++) { for(x=-range;x<=range;x++) { printf("%5d",fun(x,y)); } printf(" "); } printf("请输入两个数:"); while(scanf("%d%d",&x,&y)==2) { printf("%d ",fun(x,y)); printf("请输入两个数:"); } return 0; }
结果测试如下:
[root@master tmp]# ./1 73 74 75 76 77 78 79 80 81 72 43 44 45 46 47 48 49 50 71 42 21 22 23 24 25 26 51 70 41 20 7 8 9 10 27 52 69 40 19 6 1 2 11 28 53 68 39 18 5 4 3 12 29 54 67 38 17 16 15 14 13 30 55 66 37 36 35 34 33 32 31 56 65 64 63 62 61 60 59 58 57 请输入两个数:4 2 55 请输入两个数:1 1 3 请输入两个数:2 4 59 请输入两个数:3 3 31 请输入两个数:3 -3 49