谁有螺旋矩阵的说明?
发布网友
发布时间:2022-04-26 10:43
我来回答
共2个回答
热心网友
时间:2022-04-22 19:41
关于螺旋矩阵的说法不一,这里指的是形如
21 22................
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
的矩阵。
问题有两个:
1. 编程实现输出这个矩阵
2. 设1点的坐标是(0,0),x方向向右为正,y方向向下为正.例如:7的坐标为(-1,-1) ,2的坐标为(0,1),3的坐标为(1,1).编程实现输入任意一点坐标(x,y),输出所对应的数字。
1. 第一个问题我是采用模拟进行构造的,可以看到从1开始的方向变化始终是 right->down->left->up,
所持续走的长度为1->1->2->2->3->3->...,发现了这个规律不难写出代码了!注意下面我把1的位置设置
在((n-1)/2, (n-1)/2)的位置。
void Simulate(int n)
{
int x, y;
x = y = (n - 1) / 2; //1的位置
data[x][y] = 1;
int len = 1;
int count = 0;
int num = 2;
DIRECTION dir = RIGHT;
while(num <= n * n)
{
for(int i = 0; i < len; i++)
{
switch(dir)
{
case LEFT:
--y; break;
case RIGHT:
++y; break;
case UP:
--x; break;
case DOWN:
++x; break;
default: break;
}
data[x][y] = num++;
}
count++;
if(count == 2)
{
count = 0;
len++;
}
dir = (DIRECTION)((dir + 1) % 4);
}
}
2. 第二个问题我也是先找出规律,然后进行模拟。
首先,不难看出n*n的螺旋矩阵的右下角的坐标一定是(m, m),这里m=n-1
通过观察,可以看出 n=1的时候,右下角(0,0)的值为1,当n=2的时候,右下角(1,1)的坐标值为(3,3),当n=3的时候,右下角(2,2)的坐标值为13.直觉告诉我,这个值是关于n的二次函数,设f(n) = a*n^2 + b*n + c
联立方程组,可以求得a,b,c。 最终算出来的f(n) = 4*n^2 - 2*n + 1
下面再根据(x,y)和右下角(n-1,n-1)之间的关系,计算出值即可。这里要注意当x的值与n-1相同时,应优先考虑y与-m是否有联系。这就要求在函数中要注意x,y的判断先后顺序了。
代码如下:
//以(1,1)所在位置作为原点,向右作为x正半轴,向下作为y正半轴
int GetValue(int x, int y)
{
int m = max(abs(x), abs(y));
int rightBottom = m * m * 4 - 2 * m + 1;
int value = 0;
if(x == -m)
{
value = rightBottom + 2 * m + m - y;
}
else if( y == m)
{
value = rightBottom + m - x;
}
else if(y == -m)
{
value = rightBottom + 4 * m + x + m;
}
else if( x == m )
{
value = rightBottom - (m - y);
}
return value;
}
参考资料:http://esun.qy01.com/
热心网友
时间:2022-04-22 20:59
所谓的螺旋矩阵,指如下形式的H列*L行的矩阵:
如何编程产生呢,ChinaJavaWorld技术论坛上曾经有不少爱好者给出过自己的解答,这里选两个易理解算法的程序学习。
一、方法一
沿如图方向,沿各个矩形边框依次给矩阵的每一个元素赋值,在计算机内存中构造一个完整的螺旋矩阵,然后输出。
代码:
public class Test {
public static int[][] makeMatrix(int w, int h) {
int[][] mtr = new int[w][h];
int d = 1, x = 0, y = 0;
while(true) {
mtr[x][y] = d++;
//各方向可否前进
boolean right = x< w-1&&mtr[x+1][y]==0;
boolean down = y< h-1&&mtr[x][y+1]==0;
boolean left = x>0&&mtr[x-1][y]==0;
boolean up = y>0&&mtr[x][y-1]==0;
//判断前进方向
if(right) if(up) y--; else x++;
else if(down) if(right) x++; else y++;
else if(left) if(down) y--; else x--;
else if(up) if(left) x--; else y--;
else break;
}
return mtr;
}
public static void printMatrix(int[][] mtr) { //输出
int w = mtr.length;
int h = mtr[0].length;
for(int i=0; i< h; i++) {
for(int j=0; j< w; j++) {
System.out.print(mtr[j][i] + "\t");
}
System.out.println ();
}
}
public static void main(String[] args) {
int h = Integer.parseInt(args[0]);
int w = Integer.parseInt(args[1]);
printMatrix(makeMatrix(h,w));
}
}
二、方法二
做出数学模型, 直接计算每一个坐标上的值, 这样就不用存放一个完整的矩阵在内存中, 要频繁引用的话,可以调用这个算法预先生成一个矩阵存起来。
代码:
/** 作者:yanjj98* 基本思路:采用数学方法直接计算出矩阵元素P(x,y)的值.* 将整个矩阵看成由一个一个的矩形圈组成,矩阵中某一矩形圈上任意一点P(x,y)的值=* 位于外圈的所有点数+本圈处于点p(x,y)前面的所有点数+1 */
public class Martrix
{
private int H;
private int L;
public static void main(String argv[])
{
int h = Integer.parseInt(argv[0]);
int w = Integer.parseInt(argv[1]);
Martrix m1=new Martrix(h,w);
m1.print();
}
public Martrix()
{
this.H=3;
this.L=3;
}
public Martrix(int x,int y)
{
this.H=x;
this.L=y;
}
//计算点p(x,y)的值
public int getDotCount(int x,int y)
{
return getDotCount1(H,L,x,y) + getDotCount2(H,L,x,y) + 1;
}
//计算点P(x,y)外围矩形圈数
public static int getN(int H,int L,int x,int y)
{
return Math.min(Math.min(x,y),Math.min((H-x),(L-y)));
}
//计算点P(x,y)外围矩形圈上的点数 (等差数列,这个等差数列的公差为-8)
public static int getDotCount1(int H,int L,int x,int y)
{
int N=getN(H,L,x,y);//等差数列的项数
int S1=2*(H+L); //等差数列的第一项,即最外围矩形上的点数
int S2=2*(H+L)-8*N + 8;//等差数列的第N项,即最后一圈矩形上的点数
return (S1+S2)/2 * N; //返回等差数列的和
}
//计算与点P(x,y)处于同一个矩形圈上,且在点P前面的所有点数 (分段函数)
public static int getDotCount2(int H,int L,int x,int y)
{
int N=getN(H,L,x,y);
int x1=x-N;
int y1=y-N;
int H1=H-2*N;
int L1=L-2*N;
int count;
if(L1==0) //特列:H >=L ,L为奇数,y=(L-1)/2 实例(H=6,L=5,x=3,y=3)
return x1 ;
if(H1==0) //特列: H < L ,H为奇数,x=(H-1)/2 实例(H=5,L=6,x=3,y=3)
return y1;
if(y1==0) //一般情况:
{
count=x1;
}
else if(x1==H1) //一般情况:
{
count=H1 + y1;
}
else if(y1==L1) //一般情况:
{
count=H1 + L1 + (H1 - x1);
}
else if(x1==0) //一般情况:
{
count=H1 + L1 + (H1 - x1) + (L1 - y1);
}
else //出错情况:
{
count= -1;
}
return count;
}
//计算并输出螺旋矩阵
public void print()
{
System.out.println("H = " + H +" , " + "L = " + L);
System.out.println("******************************************");
for(int j=0;j<=L;j++)
{
for(int i=0;i<=H;i++)
{
System.out.print(getDotCount(i,j)+"\t");
}
System.out.println();
}
System.out.println("************************************");
}
}
一次运行图:
D:\java>java Martrix 8 9H = 8 , L = 9******************************************1 2 3 4 5 6 7 8 934 35 36 37 38 39 40 41 1033 60 61 62 63 64 65 42 1132 59 78 79 80 81 66 43 1231 58 77 88 89 82 67 44 1330 57 76 87 90 83 68 45 1429 56 75 86 85 84 69 46 1528 55 74 73 72 71 70 47 1627 54 53 52 51 50 49 48 1726 25 24 23 22 21 20 19 18************************************