1 条题解

  • 0
    @ 2025-8-24 22:01:58

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar piuke
    “和稀音小姐一样,今天也要做一只树懒哦。”

    搬运于2025-08-24 22:01:58,当前版本为作者最后更新于2019-08-17 16:10:14,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    好久没写博客了啊……来水一发……

    题意描述

    为什么这样一道英文题不支持提供翻译……

    给你一个n×mn\times m的矩阵和矩阵内的qq个螺旋线,在矩阵上填入螺旋线遍历到该点的编号,求最终的矩阵。

    螺旋线的由初始点和方向(顺时针或逆时针)定义,且矩阵右上角为(1,1)(1,1)
    顺时针线是由初始点向上一个单位,向右一个单位,向下两个单位,向左两个单位,再向上三个单位……以此类推。 同理,逆时针线是由初始点向上一个单位,向左一个单位,向下两个单位,向右两个单位,再向上三个单位……以此类推。

    当两条线覆盖到同一个格子时,取较小的编号。 如果螺旋线到了矩阵外,不需要处理,但是编号要保持增加,最后只输出矩阵内的元素。

    样例解释

    好像只有样例三看不懂

    样例三:

    3 3 2  
    1 1 0  
    1 2 0
    

    输出:

    1  1  4
    6  5  5
    19 18 17
    

    先看第一个螺旋线,构造出来应该是这样的:

       .  .  .  .
       .  .  .  .
       .  .  .  .
    ...10 11 12 13...
    ...9  2  3  14...
    ...8  1  4  15...
    ...7  6  5  16...
    ...20 19 18 17...
       .  .  .  .
       .  .  .  .
       .  .  .  .
    

    这是一个5×45\times 4的矩阵,但是我们只取右下角的3×33\times 3。 再只看第二个螺旋线,可得:

       .  .  .  .
       .  .  .  .
       .  .  .  .
    ...10 11 12 13...
    ...9  2  3  14...
    ...8  1  4  15...
    ...7  6  5  16...
    ...20 19 18 17...
       .  .  .  .
       .  .  .  .
       .  .  .  .
    

    这还是一个5×45\times 4的矩阵,但是我们只取左下角的3×33\times 3。 于是合并两个3×33\times3的矩阵,得到答案:

    1  1  4
    6  5  5
    19 18 17
    



    说了这么多,模拟
    强势模拟绕的过程,不是就直接走,判断出了几条界,出了四条街就停

    时间复杂度:最多不会长宽多走一倍,所以是O(4nmq)O(4nmq)

    CodeCode

    int n, m, k;
    bool out[4];
    int mp[51][51];
    inline void check(int x, int y) {
        if(x < 1) out[0] = 0;
        if(y < 1) out[1] = 0;
        if(x > n) out[2] = 0;
        if(y > m) out[3] = 0;
    }
    inline void draw(int&x, int&y, int way, int&num, char ty) {
        for(int i = 1; i <= way; i++) {
            if(ty == 'u') x--;
            if(ty == 'd') x++;
            if(ty == 'l') y--;
            if(ty == 'r') y++;
            check(x, y);
            num++;
            if(x >= 1 && y >= 1 && x <= n && y <= m)
                mp[x][y] = Min(mp[x][y], num);
        }
    }
    int main() {
        memset(mp, 0x3f, sizeof mp);
        read(n), read(m), read(k);
        for(int i = 1; i <= k; i++) {
            int x, y, ty; read(x), read(y), read(ty);
            int dis = 0, num = 1;
            out[0] = out[1] = out[2] = out[3] = 1;
            mp[x][y] = num;
            while(out[0] || out[1] || out[2] || out[3]) {
                if(ty == 0) {
                    draw(x, y, dis / 2 + 1, num, 'u'); dis++;
                    draw(x, y, dis / 2 + 1, num, 'r'); dis++;
                    draw(x, y, dis / 2 + 1, num, 'd'); dis++;
                    draw(x, y, dis / 2 + 1, num, 'l'); dis++;
                }
                else {
                    draw(x, y, dis / 2 + 1, num, 'u'); dis++;
                    draw(x, y, dis / 2 + 1, num, 'l'); dis++;
                    draw(x, y, dis / 2 + 1, num, 'd'); dis++;
                    draw(x, y, dis / 2 + 1, num, 'r'); dis++;
                }
            }
        }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j < m; j++)
                printf("%d ", mp[i][j]);
            printf("%d\n", mp[i][m]);
        }
    }
    

    至于前方的模板——https://www.luogu.org/paste/7ihr6633

    • 1

    信息

    ID
    3582
    时间
    1000ms
    内存
    63MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者