9.16华为OD机试真题 新系统 - 矩阵螺旋遍历 (Java/Py/C/C++/Js/Go)

矩阵螺旋遍历

华为OD机试真题 新系统 华为OD上机考试真题新系统 9月16号 100分题型

华为OD机试新系统真题目录点击查看: 华为OD机试新系统真题题库目录|机考题库 + 算法考点详解

题目内容

给定一个M行N列的矩阵,矩阵中每个元素是一个非负整数,从左上角(0,0)开始,按顺时针螺旋顺序遍历矩阵,对于遍历的每个数字,计算器二进制表示中1的个数,如果1的个数是3的倍数,则记录该数字的坐标。请按照顺序输出满足条件的数字的坐标列表。

螺旋遍历按照从外到内,从(0,0)出发,先向右,遇到边界或以访问元素后,按右->下-> 左->下循环转向。

输入描述

一个二维数字Array[M][N](1 <= M,N <= 10),数字行数为M,列数位N;每个数组元素是由N个非负整数组成的数组,整数范围在0,10\^9

输出描述

按遍历顺序输出满足条件的坐标,单个格式为(行索引,列索引);如果没有满足条件的数字输出空;数字0按满足条件统计输出。

样例1

输入

复制代码
3 4
1 2 3 4
5 6 7 8
9 10 11 12

输出

复制代码
(2,2) (1,2)

题解

思路:模拟

  1. 按照题意进行模拟执行代码逻辑即可。根据螺旋遍历规律
    1. 定义top bottom left right表示本次循环的四个边界
      • 初始从左至右,碰到右边界,更新上边界范围。转向从上到下
      • 碰到下边界时,更新右边界,转向从右至左。
      • 碰到左边界时,更新下边界,转向从下到上
      • 碰到上边界时,更新左边界,转向从左至右。
    2. 重复以上逻辑直到将所有元素访问之后,结束
  2. 遍历过程中二进制移位统计对应二进制1的数量,判断满足3的倍数?满足情况下加入结果数组中

这道题的逻辑和之前考过的一道题逻辑基本一致华为OD机试真题 - 数字螺旋矩阵

C++

cpp 复制代码
#include <bits/stdc++.h>
#include <vector>
using namespace std;

// 检验二进制1的数量是否为3的倍数
bool check(int num) {
    int sum = 0;
    while (num != 0) {
        if ((num & 1) != 0) {
            sum++;
        }
        num >>= 1;
    }
    return (sum % 3) == 0;
}

vector<vector<int>> solve(vector<vector<int>>& nums) {
    vector<vector<int>> ans;
    int m = nums.size();
    int n = nums[0].size();
    int total = m * n;
  
    int top = 0, bottom = m - 1, left = 0, right = n - 1;
    while (top <= bottom && left <= right) {
        for (int i = left; i <= right; i++) {
            if (check(nums[top][i])) {
                ans.push_back({top, i});
            }
        }
        top++;

        for (int i = top; i <= bottom ; i++) {
            if (check(nums[i][right])) {
                ans.push_back({i, right});
            }
        }
        right--;

        for (int i = right; i >= left ; i--) {
            if (check(nums[bottom][i])) {
                ans.push_back({bottom, i});
            }
        }
        bottom--;
        for (int i = bottom; i >= top ; i--) {
            if (check(nums[i][left])) {
                ans.push_back({i, left});
            }
        } 
        left++;                       
    }
    return ans;
}

int main() {
    int m, n;
    cin >> m >> n;
    vector<vector<int>> nums(m, vector<int>(n));
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            cin >> nums[i][j];
        }
    }
    vector<vector<int>> ans = solve(nums);
    for (int i = 0; i < ans.size(); i++) {
        if (i > 0) {
            cout << " ";
        }
        cout << "(" << ans[i][0] << "," << ans[i][1] << ")";
    }
    return 0;
}

Java

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

public class Main {

    // 检验二进制1的数量是否为3的倍数
    static boolean check(int num) {
        int sum = 0;
        while (num != 0) {
            if ((num & 1) != 0) {
                sum++;
            }
            num >>= 1;
        }
        return (sum % 3) == 0;
    }

    static List<List<Integer>> solve(int[][] nums) {
        List<List<Integer>> ans = new ArrayList<>();
        int m = nums.length;
        int n = nums[0].length;

        int top = 0, bottom = m - 1, left = 0, right = n - 1;

        while (top <= bottom && left <= right) {
            for (int i = left; i <= right; i++) {
                if (check(nums[top][i])) {
                    ans.add(Arrays.asList(top, i));
                }
            }
            top++;

            for (int i = top; i <= bottom; i++) {
                if (check(nums[i][right])) {
                    ans.add(Arrays.asList(i, right));
                }
            }
            right--;

            for (int i = right; i >= left; i--) {
                if (check(nums[bottom][i])) {
                    ans.add(Arrays.asList(bottom, i));
                }
            }
            bottom--;

            for (int i = bottom; i >= top; i--) {
                if (check(nums[i][left])) {
                    ans.add(Arrays.asList(i, left));
                }
            }
            left++;
        }

        return ans;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int m = sc.nextInt();
        int n = sc.nextInt();

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

        List<List<Integer>> ans = solve(nums);

        for (int i = 0; i < ans.size(); i++) {
            if (i > 0) {
                System.out.print(" ");
            }
            System.out.print("(" + ans.get(i).get(0) + "," + ans.get(i).get(1) + ")");
        }
    }
}

Python

python 复制代码
import sys

# 检验二进制1的数量是否为3的倍数
def check(num):
    sum = 0
    while num != 0:
        if (num & 1) != 0:
            sum += 1
        num >>= 1
    return (sum % 3) == 0


def solve(nums):
    ans = []
    m = len(nums)
    n = len(nums[0])

    top = 0
    bottom = m - 1
    left = 0
    right = n - 1

    while top <= bottom and left <= right:
        for i in range(left, right + 1):
            if check(nums[top][i]):
                ans.append([top, i])
        top += 1

        for i in range(top, bottom + 1):
            if check(nums[i][right]):
                ans.append([i, right])
        right -= 1

        for i in range(right, left - 1, -1):
            if check(nums[bottom][i]):
                ans.append([bottom, i])
        bottom -= 1

        for i in range(bottom, top - 1, -1):
            if check(nums[i][left]):
                ans.append([i, left])
        left += 1

    return ans


def main():
    data = list(map(int, sys.stdin.read().split()))
    pos = 0

    m = data[pos]
    n = data[pos + 1]
    pos += 2

    nums = []
    for i in range(m):
        nums.append(data[pos:pos + n])
        pos += n

    ans = solve(nums)

    print(" ".join(f"({x},{y})" for x, y in ans), end="")


if __name__ == "__main__":
    main()

JavaScript

js 复制代码
const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

let lines = [];

rl.on('line', line => {
    lines.push(line);
});

rl.on('close', () => {
    const data = lines.join(' ').split(/\s+/).map(Number);
    let pos = 0;

    const m = data[pos++];
    const n = data[pos++];

    const nums = [];
    for (let i = 0; i < m; i++) {
        const row = [];
        for (let j = 0; j < n; j++) {
            row.push(data[pos++]);
        }
        nums.push(row);
    }

    // 检验二进制1的数量是否为3的倍数
    function check(num) {
        let sum = 0;
        while (num !== 0) {
            if ((num & 1) !== 0) {
                sum++;
            }
            num >>= 1;
        }
        return (sum % 3) === 0;
    }

    function solve(nums) {
        const ans = [];
        const m = nums.length;
        const n = nums[0].length;

        let top = 0;
        let bottom = m - 1;
        let left = 0;
        let right = n - 1;

        while (top <= bottom && left <= right) {
            for (let i = left; i <= right; i++) {
                if (check(nums[top][i])) {
                    ans.push([top, i]);
                }
            }
            top++;

            for (let i = top; i <= bottom; i++) {
                if (check(nums[i][right])) {
                    ans.push([i, right]);
                }
            }
            right--;

            for (let i = right; i >= left; i--) {
                if (check(nums[bottom][i])) {
                    ans.push([bottom, i]);
                }
            }
            bottom--;

            for (let i = bottom; i >= top; i--) {
                if (check(nums[i][left])) {
                    ans.push([i, left]);
                }
            }
            left++;
        }

        return ans;
    }

    const ans = solve(nums);

    console.log(ans.map(([x, y]) => `(${x},${y})`).join(' '));
});

Go

go 复制代码
package main

import (
	"bufio"
	"fmt"
	"os"
)

// 检验二进制1的数量是否为3的倍数
func check(num int) bool {
	sum := 0
	for num != 0 {
		if (num & 1) != 0 {
			sum++
		}
		num >>= 1
	}
	return sum%3 == 0
}

func solve(nums [][]int) [][]int {
	ans := [][]int{}
	m := len(nums)
	n := len(nums[0])

	top, bottom := 0, m-1
	left, right := 0, n-1

	for top <= bottom && left <= right {
		for i := left; i <= right; i++ {
			if check(nums[top][i]) {
				ans = append(ans, []int{top, i})
			}
		}
		top++

		for i := top; i <= bottom; i++ {
			if check(nums[i][right]) {
				ans = append(ans, []int{i, right})
			}
		}
		right--

		for i := right; i >= left; i-- {
			if check(nums[bottom][i]) {
				ans = append(ans, []int{bottom, i})
			}
		}
		bottom--

		for i := bottom; i >= top; i-- {
			if check(nums[i][left]) {
				ans = append(ans, []int{i, left})
			}
		}
		left++
	}

	return ans
}

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var m, n int
	fmt.Fscan(in, &m, &n)

	nums := make([][]int, m)
	for i := 0; i < m; i++ {
		nums[i] = make([]int, n)
		for j := 0; j < n; j++ {
			fmt.Fscan(in, &nums[i][j])
		}
	}

	ans := solve(nums)

	for i := 0; i < len(ans); i++ {
		if i > 0 {
			fmt.Fprint(out, " ")
		}
		fmt.Fprintf(out, "(%d,%d)", ans[i][0], ans[i][1])
	}
}

C语言

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

// 检验二进制1的数量是否为3的倍数
int check(int num) {
    int sum = 0;
    while (num != 0) {
        if ((num & 1) != 0) {
            sum++;
        }
        num >>= 1;
    }
    return (sum % 3) == 0;
}

typedef struct {
    int x;
    int y;
} Point;

Point* solve(int** nums, int m, int n, int* ansSize) {
    int maxSize = m * n;
    Point* ans = (Point*)malloc(sizeof(Point) * maxSize);
    *ansSize = 0;

    int top = 0, bottom = m - 1;
    int left = 0, right = n - 1;

    while (top <= bottom && left <= right) {
        for (int i = left; i <= right; i++) {
            if (check(nums[top][i])) {
                ans[*ansSize].x = top;
                ans[*ansSize].y = i;
                (*ansSize)++;
            }
        }
        top++;

        for (int i = top; i <= bottom; i++) {
            if (check(nums[i][right])) {
                ans[*ansSize].x = i;
                ans[*ansSize].y = right;
                (*ansSize)++;
            }
        }
        right--;

        for (int i = right; i >= left; i--) {
            if (check(nums[bottom][i])) {
                ans[*ansSize].x = bottom;
                ans[*ansSize].y = i;
                (*ansSize)++;
            }
        }
        bottom--;

        for (int i = bottom; i >= top; i--) {
            if (check(nums[i][left])) {
                ans[*ansSize].x = i;
                ans[*ansSize].y = left;
                (*ansSize)++;
            }
        }
        left++;
    }

    return ans;
}

int main() {
    int m, n;
    scanf("%d %d", &m, &n);

    int** nums = (int**)malloc(sizeof(int*) * m);
    for (int i = 0; i < m; i++) {
        nums[i] = (int*)malloc(sizeof(int) * n);
        for (int j = 0; j < n; j++) {
            scanf("%d", &nums[i][j]);
        }
    }

    int ansSize;
    Point* ans = solve(nums, m, n, &ansSize);

    for (int i = 0; i < ansSize; i++) {
        if (i > 0) {
            printf(" ");
        }
        printf("(%d,%d)", ans[i].x, ans[i].y);
    }

    free(ans);

    for (int i = 0; i < m; i++) {
        free(nums[i]);
    }
    free(nums);

    return 0;
}
相关推荐
无限码力7 天前
华为OD机试真题 新系统【图的遍历】
华为od·华为od机试·华为od上机考试真题·华为od机考真题·华为od机试真题题解·华为od机考真题题解·华为机试题库
无限码力21 天前
8.26华为OD机试真题 新系统【字符串回文判断】
算法·华为od·华为od机考·华为od机试·华为od上机考试真题·华为od最新机试真题题解·华为od机试真题题库
无限码力4 个月前
2026最新华为OD机试新系统 机考真题考点分类 + 备考策略
华为od·华为od机考·华为od机试·华为od机试新系统真题·华为od机试备考策略·华为od机考真题考点详解
无限码力4 个月前
华为OD机试真题 新系统-等距二进制判断(C/C++/Py/Java/Js/Go)
华为od·华为od机考·华为od机试真题·华为od机试·华为od机试题库·华为od机试新系统真题
无限码力5 个月前
华为OD新系统机试真题 - 日志文件异常检测
华为od·华为od机考·华为od机试真题·华为od上机考试真题·华为od机考真题·华为od新系统机试真题·华为od新系统机试
无限码力5 个月前
2026最新华为OD新系统机试解析 + 最新题库 + 备考策略
华为od·华为od机考·华为od机试真题·华为od机试·华为od新系统机试真题·2026华为od新系统机试题库·华为od机考题库
无限码力8 个月前
华为OD2026最新机试双机位C卷机考真题目录含考点说明 (持续更新)
华为od·华为od机考·华为od题库·华为od机试·华为od机试双机位c卷·华为od最新上机考试题库·od机考题库
无限码力8 个月前
华为OD机试双机位C卷 - 快递投放问题 (JAVA & Python & C++ & JS & GO)
华为od·华为od机考·华为od机试·华为od机试双机位c卷·华为od上机考试真题·华为od机考真题·华为od-快递投放问题
无限码力8 个月前
华为OD机试双机位C卷 - 明日之星选举 (JAVA & Python & C/ C++ & JS & GO)
华为od·华为od机考·华为od机试真题·华为od机试·华为od上机考试双机位c卷·华为od上机考试真题·华为od机考真题