1 条题解
-
0
1.代码分析
首先,我们要理解清楚题意。题目让我们在 的网格上放置网络发射器,并且让我们覆盖的公共场所最多。要求的结果为方案数和覆盖数量。所以我们要做的就是算出每个放置点覆盖的个数,然后求最大覆盖个数和方案数量。观察到数据范围十分的小(),所以这道题可以暴力解决。
1.1读入
第一,我们开一个名为 的数组(初始化为 )用于存储当前位置的场所数量。循环读入有场所的数据并赋值。
long long r[129][129];cin>>d>>n; memset(r,0,sizeof(r)); for(int i=0; i<n; i++){ cin >> x >> y >> k; r[x][y] = k; }1.2计算覆盖场所
第二,我们循环到每一个点上来尝试放置发射器,然后计算出当前区域覆盖场所的个数。
注意到以下的几种情况。(黑框为覆盖范围)

我们要从左到右遍历每一个地方,再加到一个 变量中。(因为是以遍历位置为中心, 为覆盖正方形的边长。所以从左到右遍历,就是从中心位置横坐标点 到 。从下到上同理)
如图所示:

但是像 , 这样地方,并不能覆盖像 一样的区域(直接加或减会数组越界)。所以,我们遍历时需要对此进行特判。最无脑的方式就是:判断坐标是否越界,越界就 。
算出当前位置覆盖公共区域的个数后,我们就将答案存到 数组中。(用于计算后续答案)
for(int i=0;i<129;i++){ for(int j=0;j<129;j++){ int sum = 0; for(int m=i-d;m<=i+d;m++){ for(int l=j-d;l<=j+d;l++){ if(m<0||l<0||m>128||l>128){ sum+=0; }else{ sum+=r[m][l]; } } } a[i][j]=sum; } }1.3计算最大覆盖数和方案
现在我们已经算出每个地方覆盖数量,并以坐标的方式存在数组 中。接下来,我们设置两个变量 , 来存储最大覆盖数量和方案数(初始值为 ,因为答案最小也就是 )。依次遍历里面的元素,如果当前位置的覆盖数量大于原来的最大覆盖数量(也就是原来的 ),那就更新最大覆盖数量,并且打断方案数量,从一重新开始计算。
现在我们就可以输出啦!
long long ans=0,ans2=0; for(int i=0;i<129;i++){ for(int j=0;j<129;j++){ if(a[i][j]>ans){ //cout<<i<<" "<<j<<endl; ans=a[i][j]; ans2=1; }else if(a[i][j]==ans){ ans2++; } } } cout<<ans2<<" "<<ans;2.完整代码:
完整代码献上!!!
#include <bits/stdc++.h> using namespace std; //初始化 long long r[129][129]; //公共场所(网格模拟) long long a[129][129];//覆盖数量 long long ansx, ansy; long long maxn = -114514; int main(){ //初始化和循环读入 long long d, n, x, y, k; cin>>d>>n; memset(r,0,sizeof(r)); for(int i=0; i<n; i++){ cin >> x >> y >> k; r[x][y] = k; } //覆盖数量计算 for(int i=0;i<129;i++){ for(int j=0;j<129;j++){ int sum = 0; for(int m=i-d;m<=i+d;m++){ for(int l=j-d;l<=j+d;l++){ if(m<0||l<0||m>128||l>128){ sum+=0; }else{ sum+=r[m][l]; } } } a[i][j]=sum; } } //计算最大覆盖数量和方案 long long ans=0,ans2=0; for(int i=0;i<129;i++){ for(int j=0;j<129;j++){ if(a[i][j]>ans){ ans=a[i][j]; ans2=1; }else if(a[i][j]==ans){ ans2++; } } } //输出 cout<<ans2<<" "<<ans; }
- 1
信息
- ID
- 59
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 9
- 标签
- 递交数
- 9
- 已通过
- 7
- 上传者