Z字形扫描ccf

一、Z 字形扫描规则总结(非常关键)

对于一个 n × n 矩阵:

所有元素都位于若干条 副对角线 上

副对角线编号:

d = 行号 i + 列号 j

范围:0 ~ 2n-2

扫描顺序:

按 d = 0 → 2n-2 依次扫描

每条对角线的遍历方向固定为:

从上到下(行递增)

即 i 从小到大

⚠️ 这正好和题目给的样例完全一致

二、以样例为例(4×4)

矩阵:

1 5 3 9

3 7 5 6

9 4 6 4

7 3 1 3

按 i + j 分组:

d 元素

0 (0,0) → 1

1 (0,1),(1,0) → 5,3

2 (0,2),(1,1),(2,0) → 3,7,9

3 (0,3),(1,2),(2,1),(3,0) → 9,5,4,7

4 (1,3),(2,2),(3,1) → 6,6,3

5 (2,3),(3,2) → 4,1

6 (3,3) → 3

拼接后正是:

1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3

三、Java 实现(推荐,O(n²),n≤500 完全没问题)

java 复制代码
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();

        int[][] a = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                a[i][j] = sc.nextInt();
            }
        }

        StringBuilder sb = new StringBuilder();

        // d = i + j
        for (int d = 0; d <= 2 * n - 2; d++) {
            for (int i = 0; i < n; i++) {
                int j = d - i;
                if (j >= 0 && j < n) {
                    sb.append(a[i][j]).append(" ");
                }
            }
        }

        // 去掉末尾空格
        System.out.println(sb.toString().trim());
    }
}

一、为什么你会得到这个"错误输出"?

你得到的是:

1 5 3 3 7 9 9 5 4 7 6 6 3 4 1 3

而正确答案是:

1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3

根本原因只有一句话:

题目中的"Z 字形扫描"不是"每条对角线都同方向"

而是"对角线方向交替变化"

我之前给你的代码是:

for (d = 0 ... 2n-2)

for (i 从小到大)

输出 a[i][d-i]

👉 这叫 单向对角线扫描

👉 不是题目要求的 Zigzag

二、真正的 Zigzag 规则(以题目为准)

仍然按:

d = i + j

分组,但 遍历方向取决于 d 的奇偶性:

规则总结

d 的奇偶 遍历方向

d 为偶数 从下往上(i 大 → i 小)

d 为奇数 从上往下(i 小 → i 大)

这才是 Z 字形 的来源(方向来回折返)

三、用样例严格验证一遍(关键)

d = 2(偶数)

对角线元素:

(0,2)=3

(1,1)=7

(2,0)=9

偶数 ⇒ 反向输出:

9 7 3

✔️ 正确答案中正是这个顺序

d = 3(奇数)

(0,3)=9

(1,2)=5

(2,1)=4

(3,0)=7

奇数 ⇒ 正向输出:

9 5 4 7

✔️ 完全一致

四、修正后的正确 Java 代码 ✅

java 复制代码
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();

        int[][] a = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                a[i][j] = sc.nextInt();
            }
        }

        StringBuilder sb = new StringBuilder();

        for (int d = 0; d <= 2 * n - 2; d++) {
            if (d % 2 == 0) {
                // 偶数:从下往上
                for (int i = n - 1; i >= 0; i--) {
                    int j = d - i;
                    if (j >= 0 && j < n) {
                        sb.append(a[i][j]).append(" ");
                    }
                }
            } else {
                // 奇数:从上往下
                for (int i = 0; i < n; i++) {
                    int j = d - i;
                    if (j >= 0 && j < n) {
                        sb.append(a[i][j]).append(" ");
                    }
                }
            }
        }

        System.out.println(sb.toString().trim());
    }
}

五、为什么这种才叫"Z 字形"?

如果你把方向画出来:

↘ ↗ ↘ ↗ ↘

就会发现路径在 对角线上不断来回折返,视觉上是一个连续的 Z / 反 Z / Z / 反 Z

👉 这和 JPEG 的 Zigzag 扫描是同一个思想

六、总结一句(非常适合考试 / 面试)

Zigzag 扫描 =

按 i+j 分对角线 + 按对角线编号奇偶交替方向

相关推荐
mit6.824几秒前
几何|阻碍链
算法
有一个好名字2 分钟前
力扣-小行星碰撞
算法·leetcode·职场和发展
MM_MS2 分钟前
Halcon图像锐化和图像增强、窗口的相关算子
大数据·图像处理·人工智能·opencv·算法·计算机视觉·视觉检测
yyy(十一月限定版)4 分钟前
初始matlab
开发语言·matlab
LawrenceLan5 分钟前
Flutter 零基础入门(九):构造函数、命名构造函数与 this 关键字
开发语言·flutter·dart
listhi5205 分钟前
基于MATLAB的支持向量机(SVM)医学图像分割方法
开发语言·matlab
小璐猪头7 分钟前
专为 Spring Boot 设计的 Elasticsearch 日志收集 Starter
java
lamentropetion10 分钟前
E - Equal Tree Sums CF1656E
算法
hui函数11 分钟前
如何解决 pip install 编译报错 g++: command not found(缺少 C++ 编译器)问题
开发语言·c++·pip
代码游侠12 分钟前
应用——智能配电箱监控系统
linux·服务器·数据库·笔记·算法·sqlite