1 条题解

  • 0
    @ 2026-9-2 2:04:41

    1.代码分析

    首先,我们要理解清楚题意。题目让我们在 128×128128 \times 128 的网格上放置网络发射器,并且让我们覆盖的公共场所最多。要求的结果为方案数和覆盖数量。所以我们要做的就是算出每个放置点覆盖的个数,然后求最大覆盖个数和方案数量。观察到数据范围十分的小(128×128128 \times 128),所以这道题可以暴力解决。

    1.1读入

    第一,我们开一个名为 rr 的数组(初始化为 00)用于存储当前位置的场所数量。循环读入有场所的数据并赋值。

    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计算覆盖场所

    第二,我们循环到每一个点上来尝试放置发射器,然后计算出当前区域覆盖场所的个数。

    注意到以下的几种情况。(黑框为覆盖范围)

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

    如图所示:

    但是像 1122 这样地方,并不能覆盖像 33 一样的区域(直接加或减会数组越界)。所以,我们遍历时需要对此进行特判。最无脑的方式就是:判断坐标是否越界,越界就 +0+0

    算出当前位置覆盖公共区域的个数后,我们就将答案存到 aa 数组中。(用于计算后续答案)

     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计算最大覆盖数和方案

    现在我们已经算出每个地方覆盖数量,并以坐标的方式存在数组 aa 中。接下来,我们设置两个变量 ansansans2ans2 来存储最大覆盖数量和方案数(初始值为 00,因为答案最小也就是 00)。依次遍历里面的元素,如果当前位置的覆盖数量大于原来的最大覆盖数量(也就是原来的 ansans),那就更新最大覆盖数量,并且打断方案数量,从一重新开始计算。

    现在我们就可以输出啦!

    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

    [NOIP 2014 提高组] 无线网络发射器选址

    信息

    ID
    59
    时间
    1000ms
    内存
    128MiB
    难度
    9
    标签
    递交数
    9
    已通过
    7
    上传者