【模拟】灌溉

一、题目描述

小蓝负责花园的灌溉工作。
花园可以看成一个 n 行 m 列的方格图形。中间有一部分位置上安装有出水管。
小蓝可以控制一个按钮同时打开所有的出水管,打开时,有出水管的位置可以被认为已经灌溉好。
每经过一分钟,水就会向四面扩展一个方格,被扩展到的方格可以被认为已经灌溉好。即如果前一分钟某一个方格被灌溉好,则下一分钟它上下左右的四个方格也被灌溉好。
给定花园水管的位置,请问 k 分钟后,有多少个方格被灌溉好?

1.1 输入描述

输入的第一行包含两个整数 n, m
第二行包含一个整数 t,表示出水管的数量。
接下来 t 行描述出水管的位置,其中第 i 行包含两个数 r, c,表示第 r 行第 c 列有一个排水管。
接下来一行包含一个整数 k
其中,1 ≤ n, m ≤ 100, 1 ≤ t ≤ 10, 1 ≤ k ≤ 100

1.2 输出描述

输出一个整数,表示答案。

1.3 输入输出样例

  • 输入:
3 6
2
2 2
3 4
1
  • 输出:
9

原题链接灌溉

二、解题思路

2.1 搞懂题目在做什么

花园是方格网(比如nm列),装水管的位置一开始就被灌溉。之后每过一分钟,水会往上下左右四个方向各“蔓延”一格。比如,第1分钟水管周围的格子被灌溉,第2分钟这些新灌溉的格子又去“照顾”它们的周围。现在要算k分钟后,一共多少格子被灌溉。

2.2 一步步模拟扩散过程

  1. 标记初始水管位置

就像给班级点名,先把水管的位置记下来。比如输入里说水管在第2行第2列,就用数组标出来“这里一开始就有水”。

  1. 一分钟一分钟“放水蔓延”
    每一分钟都要处理当前所有已灌溉的格子。比如,现在有个格子有水,那它上下左右的格子(只要没超出花园边界,且没被灌溉过),这一分钟就该被“传染”有水。这里用了两个数组re1re2
  • re1存的是上一分钟的灌溉情况
  • 每一分钟开始,遍历re1里所有有水的格子,把它们的上下左右在re2里标记为有水
  • 这一分钟处理完,把re2的状态复制回re1,让re1变成当前最新的灌溉情况,准备下一分钟
  1. 数最终有多少格子有水

k分钟全模拟完,扫一遍整个花园数组,统计被标记为“有水”的格子数量,这就是答案。

2.3 举个例子理解

拿题目示例来说:

  • 初始水管在(2,2)和(3,4),标记到re1
  • 处理1分钟:
    • (2,2)的上下左右(1,2)、(3,2)、(2,1)、(2,3)被标记到re2
    • (3,4)的上下左右(2,4)、(3,3)、(3,5)被标记到re2
  • re2复制给re1,最后数re1里有水的格子,共9个。

三、代码详解

#include <bits/stdc++.h>
using namespace std;

const int N = 110;
int re1[N][N], re2[N][N];

int main(){
  int n, m;
  cin >> n >> m;

  int t;
  cin >> t;
  int r, c;
  for(int i = 1; i <= t; i++){
    cin >> r >> c;
    re1[r][c] = 1;
  }

  int k;
  cin >> k;
  for(int i = 1; i <= k; i++){
    for(int j = 1; j <= n; j++){
      for(int k = 1; k <= m; k++){
        if(re1[j][k] == 1){
          re2[j][k] = 1;
          re2[j-1][k] = 1;
          re2[j][k-1] = 1;
          re2[j+1][k] = 1;
          re2[j][k+1] = 1;
        }
      }
    }

    for(int j = 1; j <= n; j++){
      for(int k = 1; k <= m; k++){
        re1[j][k] = re2[j][k];
      }
    }
  }

  int sum = 0;
  for(int i = 1; i <= n; i++){
    for(int j = 1; j <= m; j++){
      if(re1[i][j] == 1){
        sum += 1;
      }
    }
  }
  cout << sum << '\n';

  return 0;
}

3.1 输入与初始化:

读取花园的行列数nm,出水管数量t,以及每个出水管的位置(r, c),用re1数组标记初始灌溉位置。

3.2 模拟扩散过程:

  • 外层循环k次,代表每一分钟
  • 内层双重循环遍历整个花园,若当前方格已灌溉(re1[j][k] == 1),则将其四周方格在re2中标记为已灌溉
  • 一轮扩散结束后,将re2的状态复制回re1,重置re2为下一轮做准备

3.3 结果统计:

遍历整个re1数组,统计值为1的方格数量,即最终被灌溉的方格数。


微语录:路过山水万程,祝自己与温柔重逢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值