E卷-计算网络信号-信号强度-(200分)

刷题笔记合集🔗

计算网络信号-信号强度

问题描述

在一个网格地图中,网络信号经过传递会逐层衰减,且遇到阻隔物无法直接穿透。现需要计算某个位置的网络信号值。注意:网络信号可以绕过阻隔物。

给定一个 的二维数组 ,其中:

  • 表示 是空旷位置;
  • 为正整数)表示 是信号源,信号强度为
  • 表示 是阻隔物。

信号源只有 1 个,阻隔物可能有 0 个或多个。网络信号向上下左右相邻的网格传播时,强度衰减 1。要求输出指定位置的网络信号值。

输入格式

第一行包含两个整数 ,表示网格地图的行数和列数。

第二行包含 个用空格分隔的整数,表示网格地图的状态。每 个数代表一行。

第三行包含两个整数 ,表示需要计算 的网络信号值。

输出格式

输出一个整数,表示指定位置的网络信号值。如果网络信号未覆盖到该位置,输出 0。

样例输入1

6 5
0 0 0 -1 0 0 0 0 0 0 0 0 -1 4 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0
1 4

样例输出1

2

样例输入2

6 5
0 0 0 -1 0 0 0 0 0 0 0 0 -1 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2 1

样例输出2

0

样例解释

样例 解释说明
样例1 信号源在 (2, 3) 位置,强度为 4。信号向四周传播,在 (1, 4) 位置的强度为 2。
样例2 信号源在 (2, 3) 位置,但由于阻隔物的存在,信号无法传播到 (2, 1) 位置。

数据范围

  • ,或

题解

多源BFS

这道题目本质上是一个图的广度优先搜索(BFS)问题。关键在于理解信号的传播方式和如何处理阻隔物。

解题思路如下:

  1. 首先,找到信号源的位置。
  2. 从信号源开始,使用 BFS 向四周传播信号。
  3. 在 BFS 过程中,记录每个位置的信号强度。
  4. 遇到阻隔物时,停止向该方向传播。
  5. 最后,返回指定位置的信号强度。

使用 BFS 的原因是它能够保证在遍历到某个位置时,该位置的信号强度是最大的。这是因为 BFS 是按照距离信号源的远近顺序进行遍历的。

关键点:

  • 使用队列来实现 BFS。
  • 使用一个二维数组来记录每个位置的信号强度。
  • 在遍历过程中,注意检查边界条件和阻隔物。

参考代码

  • Python
from collections import deque

def calculate_signal(m, n, grid, target_i, target_j):
    directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    signal = [[0] * n for _ in range(m)]
    
    # 找到信号源
    source = None
    for i in range(m):
        for j in range(n):
            if grid[i][j] > 0:
                source = (i, j)
                break
        if source:
            break
    
    if not source:
        return 0  # 没有信号源
    
    queue = deque([source])
    signal[source[0]][source[1]] = grid[source[0]][source[1]]
    
    while queue:
        x, y = queue.popleft()
        for dx, dy in directions:
            nx, ny = x + dx, y + dy
            if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] != -1:
                new_signal = signal[x][y] - 1
                if new_signal > 0 and new_signal > signal[nx][ny]:
                    signal[nx][ny] = new_signal
                    queue.append((nx, ny))
    
    return signal[target_i][target_j]

# 读取输入
m, n = map(int, input().split())
grid = list(map(int, input().split()))
grid = [grid[i:i+n] for i in range(0, len(grid), n)]
target_i, target_j = map(int, input().split())

# 计算并输出结果
result = calculate_signal(m, n, grid, target_i, target_j)
print(result)
  • C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SIZE 1000
#define MAX(a, b) ((a) > (b) ? (a) : (b))

// 定义队列结构
typedef struct {
    int x, y;
} Point;

typedef struct {
    Point* data;
    int front, rear, size;
} Queue;

// 初始化队列
Queue* createQueue(int capacity) {
    Queue* queue = (Queue*)malloc(sizeof(Queue));
    queue->data = (Point*)malloc(capacity * sizeof(Point));
    queue->front = queue->rear = -1;
    queue->size = 0;
    return queue;
}

// 入队
void enqueue(Queue* queue, int x, int y) {
    queue->rear = (queue->rear + 1) % (MAX_SIZE * MAX_SIZE);
    queue->data[queue->rear].x = x;
    queue->data[queue->rear].y = y;
    queue->size++;
}

// 出队
Point dequeue(Queue* queue) {
    queue->front = (queue->front + 1) % (MAX_SIZE * MAX_SIZE);
    queue->size--;
    return queue->data[queue->front];
}

// 判断队列是否为空
int isEmpty(Queue* queue) {
    return queue->size == 0;
}

int calculate_signal(int m, int n, int grid[MAX_SIZE][MAX_SIZE], int target_i, int target_j) {
    int directions[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    int signal[MAX_SIZE][MAX_SIZE] = {0};
    int source_x = -1, source_y = -1;
    
    // 找到信号源
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (grid[i][j] > 0) {
                source_x = i;
                source_y = j;
                break;
            }
        }
        if (source_x != -1) break;
    }
    
    if (source_x == -1) return 0;  // 没有信号源
    
    signal[source_x][source_y] = grid[source_x][source_y];
    
    Queue* queue = createQueue(MAX_SIZE * MAX_SIZE);
    enqueue(queue, source_x, source_y);
    
    while (!isEmpty(queue)) {
        Point current = dequeue(queue);
        int x = current.x, y = current.y;
        
        for (int i = 0; i < 4; i++) {
            int nx = x + directions[i][0];
            int ny = y + directions[i][1];
            
            if (nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] != -1) {
                int new_signal = signal[x][y] - 1;
                if (new_signal > signal[nx][ny]) {
                    signal[nx][ny] = new_signal;
                    enqueue(queue, nx, ny);
 

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

算法刷题笔记 文章被收录于专栏

本专栏收集并整理了一些刷题笔记

全部评论

相关推荐

1、自我介绍2、Agent项目是实习项目还是个人项目?有没有上线?3、拷打实习(10min)4、大模型微调,你的训练数据集是如何构建的?数据量有多大?5、在构建数据集的过程中,遇到了哪些挑战?花了多长时间?6、你之前的实习经历偏后端工程,你未来的职业规划更倾向于纯后端开发,还是希望从事与AI/大模型结合的工作?7、详细讲一下Golang中Channel的概念和作用,它是否是并发安全的?8、Channel和传统的锁(Mutex)在实现并发控制时有什么区别?各自的适用场景是什么?9、讲一下GMP模型10、当P的本地队列为空或者不为空时,它会怎么去调度G(协程)?11、Redis支持哪些数据结构12、为什么Redis的速度这么快13、如何实现一个类似淘宝搜索框的实时商品名称模糊搜索功能?14、实时输入联想与输入完成后点击搜索在技术实现上有什么本质区别?15、实时搜索通常使用什么网络协议(如WebSocket)?你了解或有使用过吗?讲一下16、请详细说明微信扫码登录的完整流程和背后发生的原理17、在微服务架构中,服务发现和负载均衡是如何实现的?18、服务注册中心(如Nacos,&nbsp;Consul)是如何工作的?服务实例如何注册和保活(如通过心跳机制)?19、讲一下Agent中的“长短期记忆”20、什么样的信息应该放在长期记忆,什么样的信息放在短期记忆?21、当对话轮数很多,上下文窗口不足时,有哪些处理策略?(如截断、压缩)22、如果要进行记忆压缩,通常有哪些方法?23、了解过Agent的设计范式吗?有哪些?24、你设计的Agent是怎么实现ReAct模式的?详细讲讲25、手撕:实现一个并发任务处理器:给定一个包含100个任务ID的列表,要求控制最大并发数为3,模拟并发调用某个外部接口(如打印ID)26、反问
三本咋了:很好的面筋
查看24道真题和解析
点赞 评论 收藏
分享
评论
2
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务