- 注册时间
- 2011-7-7
- 最后登录
- 2011-12-23
- 阅读权限
- 100
- 积分
- 271
- 精华
- 1
- 帖子
- 73
  
|
发表于 2011-7-14 15:59:20
|显示全部楼层
本帖最后由 阿良 于 2011-7-14 16:07 编辑
如下图的螺旋矩阵:
现在要一个算法,求出坐标(x,y)上的值
- 先算几个看看
- f(2,2) = 2(a + b - 2) + 1
- f(3,3) = 2(a + b - 2) +
- 2((a - 2) + (b - 2) - 2) +
- 1
- f(5,3) = 2(a + b - 2) +
- 2((a - 2) + (b - 2) - 2) +
- 1 + 5 - 3
- g(1, m) = m //g(n, m) 表示第n层第m个
- g(2, m) = 2((a - 1) + (b - 1)) + m //a和b 表示x上的长度和y上的长度
- = 2(a + b - 2) + m
- L(n) = L(1) - 8(n - 1) //表示第n层个数,每一层比上一层少8个
- = 2(a + b - 2) - 8(n - 1)
- s(n) = 2n(a + b - 2) - 8(0 + n - 1)n/2 //表示到第n层总数
- = 2n(a + b - 2) - 4n(n - 1)
- = 2n(a + b - 2n)
- g(n, m) = s(n - 1) + m //原来问题在这里,s(n) → s(n - 1)
- = 2(n - 1)(a + b - 2(n - 1)) + m
复制代码
这样f(x,y)就可以用“坐标转换”,变成求g(n,m)的问题了
先找出是第几层(n)
在第一象限时 x < (a + 1) / 2 , y < (b + 1) / 2
其它象限根据轴对称转换到第一象限再求大小即可(在对称轴上情况不需考虑了,在这不做赘述)
- x1 = x; y1 = y;
- if(x>(a+1)/2) x1 = a + 1 - x
- if(y>(b+1)/2) y1 = b + 1 - y
- n = min(x1, y1)
复制代码
再找出是第几个(m)
观察矩阵,发现每一层都是从左上角开始数数的。
第n层的横轴和纵轴长度
Lx = a - 2(n - 1)
Ly = b - 2(n - 1)
x轴长:Lx = a - 2(n - 1)
y轴长:Ly = b - 2(n - 1)
在上红边 if( (y == n) && (y != a - n + 1) ) m = x - n + 1
在右蓝边 if( (x == a - n + 1) && (y != b - n + 1) ) m = (Lx - 1) + y - n + 1
在下红边 if( (y == b - n + 1) && (y != n) ) m = (Lx + Ly - 2) + (a - n + 1) - x + 1
在左蓝边 if( (x == n) && (y != n) ) m = (Lx * 2 + Ly - 3) + (b - n + 1) - y + 1
(一开始Lx Ly忘了减1,郁闷……)
最后是代码:
- /*
- 关于一个螺旋矩阵
- 阿良
- 2011年7月14日15:20:55
- */
- function g(n, m, a, b) {
- //第n层m个的值,长a(横轴),宽b(纵轴)
- return 2 * (n - 1) * (a + b - 2 *( n - 1)) + m;
- }
- function f(x, y, a, b) {
- //这就是目标函数了 a 和 b 的含义跟g的一样
- var x1 = x, y1 = y;
- var m, n, Lx, Ly;
-
- if (x > (a + 1) / 2) x1 = a + 1 - x;
- if (y > (b + 1) / 2) y1 = b + 1 - y;
- n = Math.min(x1, y1); // 找出第n层
-
- Lx = a - 2 * (n - 1);
- Ly = b - 2 * (n - 1);
- if( (y == n) && (y != a - n + 1) ) m = x - n + 1;
- if( (x == a - n + 1) && (y != b - n + 1) ) m = (Lx - 1) + y - n + 1;
- if( (y == b - n + 1) && (y != n) ) m = (Lx + Ly - 2) + (a - n + 1) - x + 1;
- if( (x == n) && (y != n) ) m = (Lx * 2 + Ly - 3) + (b - n + 1) - y + 1;
- // 找出顺时针数第m个
- return g(n, m, a, b);
- }
- var a = 10, b = 10;
- var r = [];
- for (var y= 1; y < 11; y++) {
- r[y-1] = [];
- for (var x = 1; x < 11; x++) {
- r[y-1][x-1] = f(x, y, a, b);
- }
- }
复制代码 因为原本是在Excel里面分析的,在这里弄得很乱,我也懒得放图片了
下载附件看吧
点击进入下载-螺旋矩阵.rar |
|