螺旋矩阵
吐槽
昨天参加leetcode编程大赛,做到这题,本想着使用模拟法解决,一看数据规模达到10^9,我有预感这题应该是数学解法,那么我就不会了,之后上网查文档,发现这题是一种数学问题,看了别人的论文,想套用别人的公式,一顿提交,疯狂WA,心态爆炸,现在觉得把这题的O(1)时间复杂度的解法写出来,希望之后有人碰到这个问题时可以不用去筛各种帖子。。。
题意
一个 n 行 n 列的螺旋矩阵可由如下方法生成:
从矩阵的左上角(第 0 行第 0 列)出发,初始时向右移动;如果前方是未曾经过的格子,则继续前进,否则右转;重复上述操作直至经过矩阵中所有格子。根据经过顺序,在格子中依次填入 1, 2, 3, … , n^2,便构成了一个螺旋矩阵。
下图是一个 n = 4时的螺旋矩阵。
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
现给出矩阵大小 n 以及 i 和 j,请你求出该矩阵中第 i 行第 j 列的数是多少。
代码
cpp版
include<bits/stdc++.h>
using namespace std;
long long int n,i,j;
int main(){
scanf("%lld %lld %lld",&n,&i,&j);
++i,++j;
long long int l=min(min(i,n+1-i),min(j,n+1-j));
long long int r=4*(l-1)*(n-l+1);//上一个正方形的结尾数字
if(i==l) r+=j-l+1;
else if(j==l) r=4*l*(n-l)+(l-i+1);
else if(i==n-l+1) r+=(n-2*l+1)*2+(n+1-j)-l+1;
else if(j==n-l+1) r+=n-2*(l-1)+i-l;
printf("%lld\n",r);//答案
return 0;
}
java版
public class SpiralMatrix {
public static void main(String[] args) {
/**n是矩阵的维度,i是点的横坐标,j是点的纵坐标,a是矩阵左上角的值.*/
int n = 5,i = 3,j = 1;
int ans = helper(n,i,j);
System.out.println(ans);
}
public static int helper(int n,int i,int j){
++i;++j;
int l = Math.min(Math.min(i,n + 1 - i),Math.min(j,n + 1 - j));
int r = 4 * (l - 1) * (n - l + 1);
if (i == l) r += j - l + 1;
else if (j == l) r = 4 * l * (n - l) + (l - i + 1);
else if (i == n - l + 1) r += (n - 2 * l + 1) * 2 + (n + 1 - j) - l + 1;
else if (j == n - l + 1) r += n - 2 * (l - 1) + i - l;
return r;
}
}