zoukankan      html  css  js  c++  java
  • 无线网络发射选址

    原题:https://www.luogu.org/problem/show?pid=2038

    数据量小得出奇,直接四重循环暴力就能过。

    这道题的重点其实不是暴力,而是边界。注意到无线网络发射器能放到边缘处,但那样覆盖到地图的范围就不是一个正方形了。。

    曾经想过预处理一下每个子矩阵的公共场所的总数量,然后在这个预处理的答案中再找最大值和有最大值的个数。但我后来发现完全不必要,而且不好写。

    边界的处理。C++不能像pascal那样让数组下标变为负,所以我使用了“地图平移”操作。注意到数据范围1≤d≤20,即覆盖范围的边长的一半最大到20,那么,在读入的时候把所有坐标都+20,遍历时的坐标也同样的+20,地图边长最大128,那么遍历的长度就基本确定了:20~148.

    刚才说到四重循环,前两重循环枚举放置点,后两重循环以这个枚举点为中心直接计算和,然后维护最大值就好。

    如果你不喜欢这么做,可以按照我刚才的做法, 预处理处一个数组,这样可以只循环两层。

    AC代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #define maxn 233
     5 using namespace std;
     6 int d,n,x,y,k;
     7 int a[maxn][maxn];
     8 const int edge = 20;
     9 const int maxmap = 128;
    10 int maxv;
    11 int summat;
    12 int cnt = 1;
    13 int main(){
    14     cin >> d;
    15     cin >> n;
    16     for (int i=1;i<=n;i++){
    17         cin >> x >> y;
    18         cin >> a[x+edge][y+edge];
    19     }
    20     for (int i=edge;i<=edge+maxmap;i++)
    21         for (int j=edge;j<=edge+maxmap;j++){
    22             for (int p=i-d;p<=i+d;p++)
    23                 for (int q=j-d;q<=j+d;q++)
    24                     summat+=a[p][q];
    25             if (maxv == summat)
    26                 cnt++;
    27             else if(maxv<summat)
    28                 cnt = 1;
    29             maxv = max(summat,maxv);
    30             summat = 0;
    31         }
    32     cout << cnt << " " << maxv << endl;
    33     return 0;
    34 }
  • 相关阅读:
    ios input输入不了
    ios遇到的坑
    Linux搭建GitLab并汉化
    在Linux环境下tomcat 指定 jdk或jre版本
    SpringBoot设置默认首页
    解决MariaDB中文乱码
    使用Hexo+GitHub搭建免费个人博客
    Linux上安装node和npm
    Linux配置SSH Key到GitHub
    Linux安装Git
  • 原文地址:https://www.cnblogs.com/OIerShawnZhou/p/7457899.html
Copyright © 2011-2022 走看看