当前位置: 首页 > news >正文

蓝桥云客-染色时间

1.染色时间 - 蓝桥云课

问题描述

小蓝有一个 n 行 m 列的白色棋盘,棋盘的每一个方格都可以被染成彩色。

每个方格有一个染色时间 tij​,不同方格的染色时间可能不同。如果一个方格被触发了染色,这个方格就会在 tij​ 秒之后变成彩色,然后将自己上下左右四个方向相邻的方格触发染色。每个方格只能被触发染色一次,第一次触发之后的触发为无效触发。

给定每个方格的染色时间,在时刻 0 触发第一行第一列的方格染色,请问多长时间后整个棋盘完成染色。

输入格式

输入的第一行包含两个整数 n,m,分别表示棋盘的行数和列数。

接下来 n 行,每行 m 个正整数,相邻的整数之间用一个空格分隔,表示每个方格的染色时间。该部分的第 i 行第 j 个整数表示 tij​,即第 i 行第 j 列的方格的染色时间。

输出格式

输出一行包含一个整数,表示整个棋盘完成染色的时间。

样例输入

3
1 2 3
4 5 6

样例输出

12

评测用例规模与约定

  • 对于 30 的评测用例,1≤n,m≤10。
  • 对于 60 的评测用例,1≤n,m≤50。
  • 对于所有评测用例,1≤n,m≤500,1≤tij​≤1000。

运行限制

  • 最大运行时间:1s
  • 最大运行内存:256M

思路:

问题本质与图论建模

  1. 触发机制类比边权

    • 每个方格的染色时间 t_ij 可视为从该方格到其相邻方格的“边权”。

    • 当一个方格完成染色(触发时间 + t_ij),它才能触发相邻方格。相邻方格的触发时间等于当前方格的完成时间。

  2. 最长时间的计算

    • 所有方格完成染色的时间是其触发时间与自身染色时间之和。

    • 最终答案即为所有方格中完成时间的最大值。

  3. Dijkstra算法的适用性

    • 每个方格的触发时间需要尽可能早,这与Dijkstra求最短路径的思想一致。

    • 优先队列确保每次处理当前触发时间最小的方格,保证后续更新的正确性。


Dijkstra算法的应用步骤

  1. 初始化触发时间

    • 起点 (0,0) 的触发时间为0,其他方格初始化为无穷大(表示未被触发)。

  2. 优先队列处理

    • 每次取出队列中触发时间最小的方格,计算其完成时间。

    • 更新相邻方格的触发时间:若通过当前路径更早触发,则更新并入队。

  3. 结果计算

    • 遍历所有方格,计算触发时间与染色时间之和的最大值。

为什么不是普通的bfs?假设路径A触发时间为5秒,路径B触发时间为3秒,但路径B的节点在队列中排在路径A之后。
BFS会先处理路径A的节点,错误地将相邻方格的触发时间设为5+t,而非更优的3+t。使用优先队列是为了保证触发时间的最优性。每个节点的触发时间可能通过多条路径到达,必须选择最小的值。优先队列通过贪心策略和动态更新,确保所有节点的触发时间被正确计算,从而准确得到整个棋盘完成染色的时间。

代码:
 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 1e9;
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
struct Node{
	int time,x,y;
};
struct CompareNode 
{
    bool operator()(const Node& a, const Node& b) 
	{
        return a.time > b.time; 
    }
};
int t[505][505], dis[505][505]; 
int main() 
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) 
    {
        for (int j = 1; j <= m; ++j) 
        {
            cin >> t[i][j];
        }
    }
    memset(dis, 0x3f, sizeof dis);
    dis[1][1] = 0;
    priority_queue<Node, vector<Node>,CompareNode> pq;
    pq.push({0, 1, 1}); 
    while (!pq.empty()) 
    {
        auto node = pq.top();
        pq.pop();
        int time = node.time;
        int x = node.x;
        int y = node.y;
        if (time > dis[x][y]) 
        {
            continue;
        }
       // int current_end = time + t[x][y];
        for (int k = 0; k < 4; ++k) 
        {
            int tx = x + dx[k];
            int ty = y + dy[k];
            if (tx >= 1 && tx <= n && ty >= 1 && ty <= m) 
            {
                if (dis[tx][ty] > time + t[x][y]) 
                {
                    dis[tx][ty] = time + t[x][y];
                    pq.push({time + t[x][y], tx, ty});
                }
            }
        }
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) 
    {
        for (int j = 1; j <= m; ++j) 
        {
            ans = max(ans, dis[i][j] + t[i][j]);
        }
    }
    cout << ans << endl;
    return 0;
}

相关文章:

  • 1424.对角线遍历
  • 322 零钱兑换
  • 【大模型基础_毛玉仁】4.4 低秩适配方法
  • RocketMQ 4.x、5.x 性能对比
  • 绩效考核如何从形式化任务升级为公司战略工具?
  • 2025.3.25
  • 基于CondLaneNet论文和全卷积分割头的车道线head设计
  • QML输入控件: Dial基本用法与样式定制(1)
  • 【机器学习】imagenet2012 数据预处理数据预处理
  • K8S学习之基础五十二:k8s配置jenkins
  • Vite 与 Nuxt 深度对比分析
  • 软件设计模式-第一章
  • 数据源为postgres的多表关联flink开发需求,开发思路
  • jmeter通过json提取器获取接口返回token(超详细)
  • 3.1.2 内存池
  • Java.util包之Java.util.List接口
  • 【msyql】LInux安装Mysql
  • kubernetes高级应用之初始化容器
  • 第 6 章 | 区块链预言机操控与闪电贷攻击全解析
  • 数据结构之队列的链式结构-初始化-判断队列是否为空-入队-出队-获取队头元素
  • 肖峰读《从塞北到西域》︱拉铁摩尔的骆驼
  • 重庆大学通报本科生发14篇SCI论文处理结果
  • 这座古村,藏着多少赣韵风华
  • 国家统计局:4月份居民消费价格同比下降0.1%
  • 名帅大挪移提前开启,意属皇马的阿隆索会是齐达内第二吗
  • 印度外交秘书:“朱砂行动”不针对军事设施,无意升级事态