1.灌溉
题目描述:
小蓝负责花园的灌溉工作。花园可以看成一个 n 行 m 列的方格图形。中间有一部分位置上安装有出水管。小蓝可以控制一个按钮同时打开所有的出水管,打开时,有出水管的位置可以被认为已经灌溉好。每经过一分钟,水就会向四面扩展一个方格,被扩展到的方格可以被认为已经灌溉好。**即如果前一分钟某一个方格被灌溉好,则下一分钟它上下左右的四个方格也被灌溉好。**给定花园水管的位置,请问 k 分钟后,有多少个方格被灌溉好?
输入描述
输入的第一行包含两个整数 n,m。
第二行包含一个整数 t,表示出水管的数量。
接下来 tt 行描述出水管的位置,其中第 i 行包含两个数 r,c 表示第 r 行第 c 列有一个排水管。
接下来一行包含一个整数 k。
其中,1≤n,m≤100,1≤t≤10,1≤k≤100。
输出描述
输出一个整数,表示答案。
输入输出样例
示例 1
输入
3 6
2
2 2
3 4
1
输出
9
2.扩散
题目描述:
小蓝在一张 无限大 的特殊画布上作画。这张画布可以看成一个方格图,每个格子可以用一个二维的整数坐标表示。
小蓝在画布上首先点了一下几个点:(0, 0),(2020, 11),(11, 14),(2000, 2000),只有这几个格子上有黑色,其它位置都是白色的,每过一分钟,黑色就会扩散一点。具体的,如果一个格子里面是黑色,它就会扩散到上、下、左、右四个相邻的格子中,使得这四个格子也变成黑色(如果原来就是黑色,则还是黑色)。
请问,经过 2020 分钟后,画布上有多少个格子是黑色的。
解题思路:
这类题目,都是在某点的上下左右四个方向进行扩散。
核心问题假就是怎么判断随机的某点是否可以被扩散到呢?例如从点(1,1),扩散到点(5,5)需要多少分钟?答:8分钟。
曼哈顿算法:曼哈顿距离
两个点的横坐标的绝对值加上纵坐标的绝对值。那么只要遍历所有的可能位子的点,就是一个大矩形中的所有点,判断这个点到扩散点间的横坐标距离和纵坐标距离,如果小于给定分钟数,那么就说明这个点是可以扩散到的。
1.灌溉的c++代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a[11][2];
int n,m; //花园的行列
cin>>n>>m;
int t; //出水管数量
cin>>t;
int i, j;
for(i=1; i<=t; i++){ //出水管位置
cin>>a[i][0]>>a[i][1];
}
int k;
cin>>k; //时间 k分钟后
int count=0; //被灌溉的方格数
for(i=1; i<=n; i++){
for(j=1; j<=m; j++){
for(int c=1; c<=t; c++){
if( (abs(i-a[c][0]) + abs(j-a[c][1])) <= k){//判断输入的几个灌溉点
count++;
break; //终止循环
}
}
}
}
cout<<count;
return 0;
}
2.扩散的c++代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int ans = 0;
for (int x=0-2020; x<=2020+2020; x++){
for (int y=0-2020; y<=2020+2020; y++){
if (abs(x-0)+abs(y-0) <= 2020 || abs(x-2020)+abs(y-11) <= 2020 ||
abs(x-11)+abs(y-14) <= 2020 || abs(x-2000)+abs(y-2000) <= 2020)
ans++;
}
}
cout << ans;
}