链接直达
注意点
已知:只有一个炸弹在某街区,每个街区都有可能藏有炸弹
样例示范
输入
4 5 3 2
1 2
3 4
4 5
输出
11
说明:一个交叉点即是一个街区,实心代表街区,空心代表收到炸弹波及的街区
想法
只要遍历统计每个街区(炸弹)波及的街区之和,再通过max()获得最大值即可。
那么怎样得到某个街区(炸弹)波及的街区之和?
要知道题目给的n和m的最大值都是1e5,那么一共有n*m=1e10个街区,遍历这么多肯定会TLE。因为爆炸范围是一个 r = t 的圆,所以最好使用正方形来锁定范围,然后讲不满足的一些点(街区)需要舍去,比如【超出边界】和【距离过长】
题解
#include<bits/stdc++.h>
#define LL long long
#define IOS ios::sync_with_stdio
#define ct cin.tie(0)
using namespace std;
const int N = 100;
struct node {
int x, y;
};
int n, m;//共有n行m列
int k;//k个地方
int t;//最大范围
int ans;
//返回距离的平方
int dis(node a,node b)
{
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
void solve()
{
cin >> n >> m >> k >> t;
int mx = 0;//最终答案
for (int i = 1; i <= k; i++) {
int ans = 0;//得到炸弹在每个点波及的街区
int x, y;
cin >> x >> y;
//以(x,y)为中心,正方形遍历
for (int p = -t; p <= t; p++) {
for (int q = -t; q <= t; q++) {
node e,f;
e.x = x , e.y = y ;//e是中心点
f.x = x + p, f.y = y + q;//f是判断点
if (f.x < 1 || f.x > n || f.y < 1 || f.y > m ) continue;//边界判断
if (t * t >= dis(e, f)) ans++;//距离判断
}
}
mx = max(mx, ans);//取最大值
}
cout << mx;
}
int main()
{
IOS;
ct;
solve();
return 0;
}