螺旋队列问题

问题1:

看清以下数字排列的规律,设1点的坐标是(0,0),x方向向右为正,y方向向下为正,例如,7的坐标为(-1,-1),2的坐标为(1,0),3的坐标为(1,1)。编程实现输入任意一点坐标(x,y),输出所对应的数字。

21 22 ...

20  7  8  9 10

19  6  1  2 11

18  5  4  3  12

17 16 15 14 13

解析:规律能看出来,问题就在于如何利用它。很明显这个队列是按顺时针方向螺旋向外扩展的,我们可以把它看成一层一层往外延伸。第1层规定为中间的那个1,第2层为2到9,第三层为10到25,1、9、25.。。。。不就是平方数么?而且是连续奇数的平方数,那么可以推算第t层之内有(2*t-1)^2个数,给定坐标(x,y),如何知道该点处于第几层?层数t=max(|x|,|y|)。

#include<iostream>
#include<cmath>
using namespace std;
#define MAX(x,y) ((x)>=(y)?(x):(y))
int foo(int x,int y){
	int t=MAX(abs(x),abs(y));
	int s=(2*t+1)*(2*t+1);
	int i=t;
	int j=-t;
	for(;i>-t;--i)
		if(i==x&&j==y)return s;
		else 
			s--;
	for(;j<t;++j)
		if(i==x&&j==y)return s;
		else
			s--;
	for(;i<t;++i)
		if(i==x&&j==y)return s;
		else
			s--;
	for(;j>-t;--j)
		if(i==x&&j==y)return s;
		else
			s--;
}
int main()
{
	cout<<foo(1,1)<<endl;
	cout<<foo(-1,-1)<<endl;
	cout<<foo(1,0)<<endl;
		return 0;
}
从所在层的最大的数字开始往回循环,一旦发现移动到给定位置,返回坐标对应的值

打印结果为:


问题2:

打印矩阵:

 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

这个题目和上题类似,也是上下左右进行移动,只不过,每轮的边界要整体缩减2

#include<iostream>
#include<string>
#include<vector>
using namespace std;
#define NUM 5
int a[NUM][NUM];
void fun(int n)
{
	int i,j,s;
	i=0;j=0;s=1;
	int p=n;
	int q=0;
	int MAX=NUM*NUM;
	while(s<=MAX)
	{
		for(;j<p;++j)
			a[i][j]=s++;
		j--;
		i++;
		for(;i<p;++i)
			a[i][j]=s++;
		i--;
		j--;
		for(;j>=q;--j)
			a[i][j]=s++;
		j++;
		--i;
		for(;i>q;--i)
			a[i][j]=s++;
		i++;
		j++;
		p-=1;
		q+=1;
	}
}

int main()
{
	fun(NUM);
		for(int i=0;i<NUM;++i){
		for(int j=0;j<NUM;++j)
		{
			printf("%d ",a[i][j]);
		}
		printf("\n");
	}
	return 0;
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值