vlambda博客
学习文章列表

[c++&python]语法基础4.20(数组)最后的压轴

如下代码展示的是矩形边界法:

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

int main(){
    int n, m, i, j, count = 1;
    scanf("%d %d", &n, &m);
    int M[n][m], l = 0, r = m - 1, t = 0, b = n - 1;
    while (l <= r or t <= b){
        for (i = l; i <= r and t <= b; i++){
            M[t][i] = count++;
        }
        t ++;
        for (i = t; i <= b and l <= r; i++){
            M[i][r] = count++;
        }
        r --;
        for (i = r; i >= l and t <= b; i--){
            M[b][i] = count++;
        }
        b --;
        for (i = b; i >= t and l <= r; i--){
            M[i][l] = count++;
        }
        l ++;
    }
    for (i = 0; i < n; i++){
        for (j = 0; j < m; j++) printf("%d ", M[i][j]);
        printf("\n");
    }
}

其实还有一种y总说过的通法,那就是设立dx和dy。我这儿的代码和y总的还不一样,是因为自己不会在判定上使用数组越界的方法。我把数组长和宽都多开了2个单位,在最外围筑起了整型数最高墙 。这样就能在输出的目标矩形上搜索相近上下左右一格的时候就不会越界了。

这有个

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

int n, m;
int main(){
    int i = 0, j = 0, count, d = 1;
    scanf("%d %d", &n, &m);
    int M[n + 2][m + 2] = {0}, l = 1, r = m, t = 1, b = n;
    for (i = 0; i < n + 2; i++){
        for (j = 0; j < m + 2; j++){
            if (i == 0 or j == 0 or i == n + 1 or j == m + 1) M[i][j] = 2147483647;
        }
    }
    i = 1, j = 1;
    int di[] = {-1010}, dj[] = {010-1};
    for (count = 1; count <= m * n; count++){
        M[i][j] = count;
        int a = i + di[d], b = j + dj[d];
        if (a < 1 or b < 1 or a > n or b > m or M[a][b] > 0){
            d = (d + 1) % 4;
            a = i + di[d], b = j + dj[d];
        }
        i = a, j = b;
    }
    for (i = 1; i <= n; i++){
        for (j = 1; j <= m; j++) printf("%d ", M[i][j]);
        printf("\n");
    }
}

n, m = map(int, input().split())
if __name__ == '__main__':
    M = [[0] * (m + 2for i in range(n + 2)]
    for i in range(n + 2):
        for j in range(m + 2):
            if (i == 0 or j == 0 or i == n + 1 or j == m + 1):
                M[i][j] = 2147483647
    i, j, d = 111
    di, dj = [-1010], [010-1]
    for count in range(1, m * n + 1):
        M[i][j] = count
        a, b = i + di[d], j + dj[d]
        if (a < 1 or b < 1 or a > n or b > m or M[a][b] > 0):
            d = (d + 1) % 4
            a, b = i + di[d], j + dj[d]
        i, j = a, b
        
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            print(M[i][j], end = " ")
        print(end = "\n")

至于算法复杂度,没砍边界矩形方法,和指针相对位置搜索的方法,算法时间复杂度都是 ,但是y总推荐的相对位置搜索方法是个很不错的通法,对未来的象棋算法题的马走日、车、象/主教的走法都有个不错的判定依据。

举个例子,马走日的dx和dy就分别是{-2,-1,1,2,2,1,-1,-2}和{1,2,2,1,-1,-2,-2,-1},不考虑判定边界就有8种走位。如果马的上下左右四个方向有棋子堵住的话也可以作为判定条件。马的走法可以找广度优先或者深度优先的算法,不过那就是后话了。

耗时比较(python默认成把c++的最优算法翻译成python):

序号 语言或方法 算法复杂度 耗时(ms) 打码难度
1 c++缩小边界
14 3
2 c++相对位置
14 2
3 python
1300 1