• 洛谷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;
    }
    
  • 相关阅读:
    leetcode 1. 两数之和
    leetcode 671. 二叉树中第二小的节点
    leetcode 100. 相同的树
    leetcode 110. 平衡二叉树
    leetcode 144. 二叉树的前序遍历
    1066. Root of AVL Tree (25)
    leetcode 100 相同的树
    leeCode 515 在每个树行中找最大值
    LeetCode 31.下一个排列
    面向对象UML中类关系
  • 原文地址:https://www.cnblogs.com/quanjun/p/12698533.html
Copyright © 2020-2023  润新知