洛谷P2239 螺旋矩阵 题解 模拟

题目链接:https://www.luogu.com.cn/problem/P2239

最暴力的解法就是从左上角开始遍历,一开始往右走,到头了右转往下走,到头了右转往左走,到头了右转往上走,……,一次循环。

此算法的时间复杂度为 (O(n^2) = O(9 imes 10^8)),在洛谷是可以过的。

但是我们其实可以把矩阵看成一个个圈,可以发现:最外面的圈一共有 (4 imes (n-1)) 个数字,第 (2) 外面的圈一共有 (4 imes (n-3)) 个数字,……,第 (i) 圈一共有 (4 imes (n-2 cdot i + 1)) 个数字……(如果 (n) 为奇数则最后那一圈就只有一个数字)。

而根据给我们的坐标 ((i,j)) 我们可以快速确定这个点在第 (k = min(min(i,n-i+1), min(j,n-j+1))) 圈,而第 (1) 圈到第 (k-1) 圈的数字总共有

[sum_{i=1}^{k-1} 4 imes (n - 2 cdot i + 1) = 4 cdot (n + 1 - k) cdot (k-1) ]

而第 (k) 圈的起始位置为 ((k,k)) ,我们从这里开始判断即可。

  • 如果 (i = k),则 ((i,j)) 编号为 (4 cdot (n + 1 - k) cdot (k-1) + 1 + j - k)
  • 否则,如果 (j = n+1-k),则 ((i,j)) 编号为 (4 cdot (n + 1 - k) cdot (k-1) + 1 + (n-2 cdot k+1) + i-k)
  • 否则,如果 (i = n+1-k),则 ((i,j)) 编号为 (4 cdot (n + 1 - k) cdot (k-1) + 1 + 2 cdot (n-2 cdot k+1) + (n+1-k)-j)
  • 否则,如果 (j = k),则 ((i,j)) 编号为 (4 cdot (n + 1 - k) cdot (k-1) + 1 + 3 cdot (n-2 cdot k+1) + (n+1-k) - i)

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
int n, i, j, k, ans;
int main() {
    cin >> n >> i >> j;
    k = min( min(i, n+1-i), min(j, n+1-j) );
    ans = 4 * (n+1-k) * (k-1) + 1;
    if (i == k) ans += j-k;
    else if (j == n+1-k) ans += (n-2*k+1) + i-k;
    else if (i == n+1-k) ans += 2*(n-2*k+1) + (n+1-k)-j;
    else ans += 3*(n-2*k+1) + (n+1-k)-i;
    cout << ans << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/quanjun/p/12698533.html