首页 > 其他分享 >洛谷题单指南-前缀和差分与离散化-P1884 [USACO12FEB] Overplanting S

洛谷题单指南-前缀和差分与离散化-P1884 [USACO12FEB] Overplanting S

时间:2024-07-29 15:57:14浏览次数:18  
标签:cnt 格子 USACO12FEB int 洛谷题 P1884 差分 ++ 数组

原题链接:https://www.luogu.com.cn/problem/P1884

题意解读:给定n个矩形的平面直角坐标系下左上角、右下角的坐标,计算这n个矩形能覆盖的的格子数。

解题思路:

直观上来看,此题是一个差分应用,针对二维差分数组,将n个矩形区域内每个格子的值加1,然后统计有多少个不为0的格子即可。

但是!坐标值取值范围是−10^8≤x1​,y1​,x2​,y2​≤10^8,定义二维数组会爆内存,枚举时间也无法保证。因此,需要将坐标值进行离散化!

第一步:将所有坐标值读入,离散化处理

这里,介绍一个借助于map来离散化的方式,设c[]是所有坐标排序、去重后的数组,h是一个map<int,int>

将所有真实坐标数字映射到他的相对位置只需要:

for(int i = 1; i <= cnt; i++)
{
    h[c[i]] = i; //借助于map,保存原数字与离散化之后数字的关系
}

第二步:将离散化后的n个矩形区域进行差分数组+1

这里,要注意,对于二维差分数组子矩阵每个格子加上1,格子的坐标应该是(x1,y1-1)(x2,y2-1)

对应操作为:

 //在差分矩阵上对区间进行+1操作,注意求面积时(x2,y2)不包括
for(int i = 1; i <= n; i++)
{
    a[X1[i]][Y1[i]] += 1;
    a[X2[i]][Y1[i]] -= 1;
    a[X1[i]][Y2[i]] -= 1;
    a[X2[i]][Y2[i]] += 1;
}

第三步:计算还原的前缀和数组

for(int i = 1; i < cnt; i++)
    for(int j = 1; j < cnt; j++)
        s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];

第四步:根据前缀和数组不为0的格子,计算格子对应真实格子的数量

 //计算答案
for(int i = 1; i < cnt; i++)
    for(int j = 1; j < cnt; j++)
        if(s[i][j] > 0) ans += 1ll * (c[i + 1] - c[i]) * (c[j + 1] - c[j]);

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 1005;

int X1[N], Y1[N], X2[N], Y2[N];
int c[4 * N], cnt;
map<int,int> h;
int a[4 * N][4 * N]; //差分矩阵
int s[4 * N][4 * N]; //二维前缀和
int n;
long long ans;

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> Y1[i] >> X2[i] >> Y2[i] >> X1[i]; //输入时将平面直角坐标系转换为二维数组坐标
        c[++cnt] = X1[i];
        c[++cnt] = Y1[i];
        c[++cnt] = X2[i];
        c[++cnt] = Y2[i];
    }
    //排序、去重
    sort(c + 1, c + cnt + 1);
    int j = 0;
    for(int i = 1; i <= cnt; i++)
        if(i == 1 || c[i] != c[i - 1])
            c[++j] = c[i];
    cnt = j;
    //离散化
    for(int i = 1; i <= cnt; i++)
    {
        h[c[i]] = i; //借助于map,保存原数字与离散化之后数字的关系
    }
    for(int i = 1; i <= n; i++)
    {
        X1[i] = h[X1[i]];
        Y1[i] = h[Y1[i]];
        X2[i] = h[X2[i]];
        Y2[i] = h[Y2[i]];
    }
    //在差分矩阵上对区间进行+1操作,注意求面积时(x2,y2)不包括
    for(int i = 1; i <= n; i++)
    {
        a[X1[i]][Y1[i]] += 1;
        a[X2[i]][Y1[i]] -= 1;
        a[X1[i]][Y2[i]] -= 1;
        a[X2[i]][Y2[i]] += 1;
    }
    //还原前缀和
    for(int i = 1; i < cnt; i++)
        for(int j = 1; j < cnt; j++)
            s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
    //计算答案
    for(int i = 1; i < cnt; i++)
        for(int j = 1; j < cnt; j++)
            if(s[i][j] > 0) ans += 1ll * (c[i + 1] - c[i]) * (c[j + 1] - c[j]);
    cout << ans;
    return 0;
}

 

标签:cnt,格子,USACO12FEB,int,洛谷题,P1884,差分,++,数组
From: https://www.cnblogs.com/jcwy/p/18330284

相关文章

  • 洛谷题单指南-前缀和差分与离散化-P1496 火烧赤壁
    原题链接:https://www.luogu.com.cn/problem/P1496题意解读:给定n个区间[a,b),计算所有区间覆盖的总长度。解题思路:方法1、离散化先思考一种比较直观的思路:既然要计算多个区间覆盖的总长度,可以枚举每一个区间[a,b),通过一个桶数组来标记区间中所有的点f[x]=1,最终统计所有为1的......
  • 洛谷题单指南-前缀和差分与离散化-P3397 地毯
    原题链接:https://www.luogu.com.cn/problem/P3397题意解读:给定一个n*n的矩阵,每个元素初始值为0,再将m个子矩阵中的元素都增加1,统计每个元素最终的值。解题思路:1、暴力法枚举每一个子矩阵,将对应元素值加1,时间复杂度为1000^3,不可行。2、二维差分对于给定二维数组s[][],给指定区......
  • 洛谷题单指南-前缀和差分与离散化-P2367 语文成绩
    原题链接:https://www.luogu.com.cn/problem/P2367题意解读:对于数组s[],给指定q个区间[x,y]里每个数增加z,计算操作之后最小的数。解题思路:1、暴力做法对于每一个区间[x,y],枚举给每一个数增加z,然后遍历查找最小值,总体时间复杂度为O(N^2),不可行。2、一维差分对于给指定区间[x,......
  • 洛谷题单指南-前缀和差分与离散化-P1314 [NOIP2011 提高组] 聪明的质监员
    原题链接:https://www.luogu.com.cn/problem/P1314题意解读:计算m个检验值之和,计算与s差值绝对值的最小值。解题思路:1、首先要搞懂检验值是如何计算的如上图,对于每一个区间的检验值yi,表示为:yi="该区间重量>=W的矿石个数" ✖️"该区间>=W的矿石价值之和"检验值y即所有yi(1<=......
  • 洛谷题单指南-前缀和差分与离散化-P8218 【深进1.例1】求区间和
    原题链接:https://www.luogu.com.cn/problem/P8218题意解读:对于数组a[N],给定m个区间l~r,求每个区间所有元素之和。解题思路:先思考暴力做法:对于每一个区间[l,r],累加a[l]~a[r]所有元素,时间复杂度最坏为10^5*10^4,不可行。一维前缀和:设s[N]是a[N]的前缀和数组,即对于每一个s[i......
  • [NOIP2008 提高组] 笨小猴(洛谷题号P1125)
    [NOIP2008提高组]笨小猴题目描述笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大!这种方法的具体描述如下:假设maxn是单词中出现次数最多的字母的出现次数,minn是单词中出现次数最少的字母的......
  • 洛谷题单指南-动态规划3-P1220 关路灯
    原题链接:https://www.luogu.com.cn/problem/P1220题意解读:按坐标顺序排列1~n个路灯,每个路灯有不同的功耗,老张从位置c开始关灯,第一时间关掉c位置的灯,每次关掉一个灯之后,可以往右走、也可以往左走关下一个灯,老张速度是1m/s,求所有灯都关掉所消耗的最少功耗。解题思路:由题意分析,关......
  • 洛谷题单指南-动态规划3-P4342 [IOI1998] Polygon
    原题链接:https://www.luogu.com.cn/problem/P4342题意解读:环中节点表示数字,边表示运算符,可以任意断一条边,其余节点两两按边的符号计算,求结果的最大值,以及最大值是断开那些边可以得到。解题思路:题意中有几个个关键信息:环形,节点数为n,边数为n任意断一条边,即可以从任意节点开始,......
  • 洛谷题单指南-动态规划3-P1070 [NOIP2009 普及组] 道路游戏
    原题链接:https://www.luogu.com.cn/problem/P1070题意解读:1~n个环形机器人工厂,相邻工厂之间的道路是1~n,每个时刻可以从任意工厂购买机器人,走不超过p时间,不同工厂购买机器人花费不同的金币,不同时刻走到不同道路也能得到不同的金币,问一共m时间,最多可以得到多少金币(需减去购买机器人......
  • 洛谷题单指南-动态规划3-P1063 [NOIP2006 提高组] 能量项链
    原题链接:https://www.luogu.com.cn/problem/P1063题意解读:本质上是一个环形石子合并问题,计算合并产生的最大能量。解题思路:对于环形DP问题,可以把环拆开,并复制2倍长度,然后用1~n的区间长度去枚举1、状态表示设structnode{inthead,tail}用于表示每一个项链节点,其中有头、尾......