螺旋队列

#程序员面试宝典学习笔记
问题描述:
原图
看清以上数字的排列,设1所在的位置是(0,0),x的方向向右为正,y的方向向下为正。例如7的坐标是(-1,-1),2的坐标是(1,0),3的坐标是(1,1)。编程实现输入任意一坐标(x,y),输出所对应位置的数字。

分析:1.先注意到1,2,3,4…数字的走向,会发现它是呈出螺旋状,以及它的方向是顺时针,如图。2.根据题意,它的坐标方向如图。
螺旋状
坐标走向
3.要具有一定的敏感性。对于此类型图,应有规律可循,在结合以1为中心(可看做圆心),画圆,1的左,右,上,下,甚至是对角线方位。

4.而且此题结合了,坐标,那我们应该注意的是,某个数字和坐标轴橡胶的位置,这样就会出现四个位置,以及和坐标有关的x值不变,或者y值不变,即需要考虑与坐标轴平行或者垂直的情况,如图。

坐标轴
5.还要考虑 平方或者是2倍的关系,因为相对简单来想到去推导各元素是不是满足某种关系。

牢牢记住,把1当做圆心(中央来看)
解题:把前面分析的进行组合就用例子来套(以0开始)。
#0,单独把1圈出来,只有一个1
#1,把2,3 ,4,5,6,7,8 ,9圈出来
如图:画圈

然后加上坐标来分析
找关系
在进行进一步的研究找规律
然后此时我们需要专门的去简历培养一种新思维,给圈命名,把单独的一个1,为圈0。 2,3,4,5,6,7,8,9所在的圈为圈1,以此类推,注意是以1为圆心那样的画圆。现在把上图变一下:
普遍规律
t代表的是所在圈数,那要计算某个数值所在的圈数,要发现,它的坐标x,y,而x,y有正负,就考虑绝对值,或者添加“-”号(相反数),然后发现无论是单独的x,y还是并存的x,y。|x|,|y|的值都是<=t。
所以我们需要 1.使得 x,y坐标值都为非负;
2.在1的基础上比较 大小,判断所在圈数。
3.得到t值 带入上述式子(比如(2t-1)^2+t)得到5个特殊的值
4.如果不是以上5个特殊方位的值,则需考虑坐标轴平行情况 以及图的螺旋走向。
例题
比如现在要求12,那么我们已经知道11的信息((2
t-1)^2
+t)且11的y值为0,再来对比12和11的差一点,他们x值相同,y不同,所以12是(2*t-1)^2+t+y。

对于其他位置的数类似,现在总结:(u为所求,增加方向是否满足螺旋的顺时针方向或者是与坐标轴的正向平行, 以x或y的值和圈数t有关来划分)
x = t,队列增长方向和 y 轴一致,(y = 0)数值为 (2t-1)2 + t,所以 u = (2t-1)2 + t + y

y = t,队列增长方向和 x 轴相反,(x = 0)数值为 (2t-1)2 + 3t,所以 u = (2t-1)2 + 3t - x

x = -t,队列增长方向和 y 轴相反,(y = 0)数值为 (2t-1)2 + 5t,所以 u = (2t-1) 2 + 5t - y

y = -t,队列增长方向和 x 轴一致,(x = 0)数值为 (2t-1)^2 +7t,所以 u = (2t-1) 2 +7t + x
增长方向
橙色箭头为螺旋增长方向,如果橙色线 和坐标轴平行时,箭头方向不一致,则增长方向为相反,否则,为一致。
参考代码(以下有文章链接):
#include
#include
using namespace std;

int spiralqueue(int x,int y){
int t=max(abs(x),abs(y));
int v=(2t-1)(2t-1);
int u;
if(x==-t)
u=v+(5
t-y);
else if(y==-t)
u=v+(7t+x);
else if(y==t)
u=v+(3
t-x);
else
u=v+(t+y);
return u;
}
int main(){
int x,y;
for(y=-4;y<=4;y++){
for(x=-4;x<=4;x++)
printf("%5d",spiralqueue(x,y));
printf("\n");
}
system(“pause”);
return 0;
}

结尾:1.不知不觉,写了挺多的,希望自己继续努力!
2.这道题有个难点是,这个数字之间的规律不太好找,需要一定的数学基础和好的观察力。希望日后多多积累,减少这种无处下手的感觉,共勉!
3.附上上面代码的链接,十分感谢,帮助我理解螺旋队列的问题。
CSDN博主「ruan875417」的原创文章
原文链接:https://blog.csdn.net/ruan875417/article/details/43672327

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值