螺旋队列(内螺旋队列以及外螺旋队列)

本文介绍了如何实现外螺旋队列,即队列元素按向外螺旋形状排列。通过分析坐标与数值的关系,可以计算出任意坐标点对应的数字。关键在于确定每圈的最大值,并根据坐标位置计算具体数值。代码实现参考了相关博客和书籍。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

外螺旋队列


上图即为外螺旋队列的样子,即向外螺旋伸展。

问题:设1的坐标是(0,0),x方向向右为正,y方向向下为正,例如,7的坐标为(-1,-1),2的坐标为(1,0)。编程实现输入任意一点坐标(x,y),输出所对应的数字!

思路:

从图中不难发现,每圈最大值max=(2*t+1)(2*t+1),即紫色方块中的值,t为由内往外的圈数,t>=0。如图每圈最大值分别是1、9、25、49、81........,算出每圈的max后,就分4条边分别计算每圈的其他值。通过坐标落在该圈4条边的哪条边上,按照不同的公式计算出具体坐标点的值。




从上图中可以看出,四个边框中间的值对于求值十分有帮助,并且这四个值也很容易求得:

1,上边框中点值: max - t

1,左边框中点值: max -3t

1,下边框中点值: max - 5t

1,上边框中点值: max - 7t

对于落在四个边框上的值可以用加减x或y直接求得:

int Spiral1(int x,int y)
{
	int t = max(abs(x),abs(y));
	int u = 2 * t;
	int max = ( u + 1)*(u + 1);
	int v; 
	if (x == -t) //左边框 
		v = max - 3 * t - y;
	else if (y == -t) //上边框 
	 	v = max - t + x;
	else if (y == t) //下边框 
		v = max - 5 * t - x;
	else   //右边框 
		v = max - 7 * t + y;
	return v;
}
内螺旋队列

    1    2    3    4    5
   16   17   18   19    6
   15   24   25   20    7
   14   23   22   21    8
   13   12   11   10    9
如上所示的即为内螺旋队列,即逐渐向内螺旋收缩。

具体的求解方式即控制x和y的左边逐渐从外圈向内圈收缩,首先从上边框向右伸展,然后从右边框向下伸展,然后从下边框从右往左伸展,再从左边框从下往上伸展。

代码:

int Spiral2(int **a,int n)
{
	int m = 1,i,j;
	for(i = 0; i < n/2; i++)
	{
		/* 上边框 */
		for(j = 0; j < n - i; j++)
		{
			if(a[i][j] == 0)
				a[i][j] = m++;
		}
		/* 右边框 */ 
		for(j = i + 1;j < n - i; j++)
		{
			if(a[j][n-i-1] == 0)
				a[j][n-i-1] = m++;
		}
		/* 下边框 */ 
		for(j = n - i -1; j > i;j--)
		{
			if(a[n-i-1][j] == 0)
				a[n-i-1][j] = m++;
		}
		/* 左边框 */ 
		for(j = n - i -1;j > i; j--)
		{
			if(a[j][i] == 0)
				a[j][i] = m++;
		}
		if(n & 0x1)
			a[n>>1][n>>1] = m;
	}
	
} 
测试程序(注意C++申请动态二维数组的方式):

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
inline int max(int x,int y)
{
	return x>y?x:y;
}

int Spiral1(int x,int y)
{
	int t = max(abs(x),abs(y));
	int u = 2 * t;
	int max = ( u + 1)*(u + 1);
	int v; 
	if (x == -t) //左边框 
		v = max - 3 * t - y;
	else if (y == -t) //上边框 
	 	v = max - t + x;
	else if (y == t) //下边框 
		v = max - 5 * t - x;
	else   //右边框 
		v = max - 7 * t + y;
	return v;
}

int Spiral2(int **a,int n)
{
	int m = 1,i,j;
	for(i = 0; i < n/2; i++)
	{
		/* 上边框 */
		for(j = 0; j < n - i; j++)
		{
			if(a[i][j] == 0)
				a[i][j] = m++;
		}
		/* 右边框 */ 
		for(j = i + 1;j < n - i; j++)
		{
			if(a[j][n-i-1] == 0)
				a[j][n-i-1] = m++;
		}
		/* 下边框 */ 
		for(j = n - i -1; j > i;j--)
		{
			if(a[n-i-1][j] == 0)
				a[n-i-1][j] = m++;
		}
		/* 左边框 */ 
		for(j = n - i -1;j > i; j--)
		{
			if(a[j][i] == 0)
				a[j][i] = m++;
		}
		if(n & 0x1)
			a[n>>1][n>>1] = m;
	}
	
} 

int main()
{
	int x,y;
	for(y = -4;y <= 4; y++){
		for( x = -4; x <= 4; x++){
			cout<<setw(5)<<Spiral1(x,y);
		}
		cout<<endl;
	}
	
	cout<<endl;
	int **a = new int* [8];
	for(int i = 0; i < 8; i++){
		a[i] = new int[8];
		memset(a[i],0,8*sizeof(int));
	}
	
	Spiral2(a,5); 
	for(y = 0;y < 5; y++){
		for( x = 0; x < 5; x++){
			cout<<setw(5)<<a[y][x];
		}
		cout<<endl;
	}
	
	for(int i = 0; i < 8; i++)
		delete [] a[i];
	delete [] a;
}

输出:

   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

    1    2    3    4    5
   16   17   18   19    6
   15   24   25   20    7
   14   23   22   21    8
   13   12   11   10    9


REF:

1,http://blog.youkuaiyun.com/yhmhappy2006/article/details/2934435

2,程序员面试宝典 第三版 P91
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值