Acwing-121-赶牛入圈(二分, 二维前缀和,离散化)

链接:

https://www.acwing.com/problem/content/123/

题意:

农夫约翰希望为他的奶牛们建立一个畜栏。

这些挑剔的畜生要求畜栏必须是正方形的,而且至少要包含C单位的三叶草,来当做它们的下午茶。

畜栏的边缘必须与X,Y轴平行。

约翰的土地里一共包含N单位的三叶草,每单位三叶草位于一个1 x 1的土地区域内,区域位置由其左下角坐标表示,并且区域左下角的X,Y坐标都为整数,范围在1到10000以内。

多个单位的三叶草可能会位于同一个1 x 1的区域内,因为这个原因,在接下来的输入中,同一个区域坐标可能出现多次。

只有一个区域完全位于修好的畜栏之中,才认为这个区域内的三叶草在畜栏之中。

请你帮约翰计算一下,能包含至少C单位面积三叶草的情况下,畜栏的最小边长是多少。

思路:

离散化之后搞一下二维前缀和.再查询就可以降到500^2*log(1000)左右.

代码:

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

struct Node
{
    int x, y;
    int node;
}node[510];
int Map[10000][10000];
int Number[2010];
int c, n, pos;

bool Check(int len)
{
    for (int x1 = 1, x2 = 1;x2 <= pos;x2++)
    {
        while (Number[x2]-Number[x1]+1 > len)
            x1++;
        for (int y1 = 1, y2 = 1;y2 <= pos;y2++)
        {
            while (Number[y2]-Number[y1]+1 > len)
                y1++;
            if (Map[x2][y2]-Map[x2][y1-1]-Map[x1-1][y2]+Map[x1-1][y1-1] >= c)
                return true;
        }
    }
    return false;
}

int main()
{
    scanf("%d %d", &c, &n);
    int x, y;
    pos = 0;
    for (int i = 1;i <= n;i++)
    {
        scanf("%d%d", &node[i].x, &node[i].y);
        Number[++pos] = node[i].x;
        Number[++pos] = node[i].y;
    }
    sort(Number+1, Number+1+2*n);
    pos = unique(Number+1, Number+1+2*n)-(Number+1);
    for (int i = 1;i <= n;i++)
    {
        node[i].x = lower_bound(Number+1, Number+1+pos, node[i].x)-Number;
        node[i].y = lower_bound(Number+1, Number+1+pos, node[i].y)-Number;
        Map[node[i].x][node[i].y]++;
    }
    for (int i = 1;i <= pos;i++)
    {
        for (int j = 1;j <= pos;j++)
            Map[i][j] = Map[i][j]+Map[i-1][j]+Map[i][j-1]-Map[i-1][j-1];
    }
    int l = 1, r = 10000;
    int res = 10000;
    while (l < r)
    {
//        cout << l << ' ' << r << endl;
        int mid = (l+r)/2;
        if (Check(mid))
        {
            r = mid;
        }
        else
            l = mid+1;
    }
//    cout << r << endl;
    printf("%d\n", r);

    return 0;
}
/*
9 9
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
1000 1000
 */

原文地址:https://www.cnblogs.com/YDDDD/p/11479835.html

时间: 2024-10-01 21:39:46

Acwing-121-赶牛入圈(二分, 二维前缀和,离散化)的相关文章

切蛋糕(二分)(二维前缀和)

观察数据范围,n*m比较小,所以我们预先处理出前缀和. 然后我们可以考虑写一个函数来计算二维前缀和(二维前缀和大家都会的吧qwq,那我就不说了,就是要注意一下哪个是横轴哪个是纵轴) 之后就是二维上的二分位置,然后check看看符不符合二分出来的ans. 注:一半求最大化最小值和最小化最大值的问题,都可以往二分想.我们可以把最优化问题二分后来check转化为判定问题. #include<cstdio> #include<cstring> #include<iostream>

Acwing-99-激光炸弹(二维前缀和)

链接: https://www.acwing.com/problem/content/101/ 题意: 一种新型的激光炸弹,可以摧毁一个边长为 R 的正方形内的所有的目标. 现在地图上有 N 个目标,用整数Xi,Yi表示目标在地图上的位置,每个目标都有一个价值Wi. 激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆炸范围,即那个边长为 R 的正方形的边必须和x,y轴平行. 若目标位于爆破正方形的边上,该目标不会被摧毁. 求一颗炸弹最多能炸掉地图上总价值为多少的目标. 思路: 二维前缀和搞

二维前缀和之激光炸弹

原题链接:https://www.acwing.com/problem/content/description/101/ 一种新型的激光炸弹,可以摧毁一个边长为 RR 的正方形内的所有的目标. 现在地图上有 NN 个目标,用整数Xi,YiXi,Yi 表示目标在地图上的位置,每个目标都有一个价值WiWi . 激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆炸范围,即那个边长为 RR 的正方形的边必须和x,yx,y 轴平行. 若目标位于爆破正方形的边上,该目标不会被摧毁. 求一颗炸弹最多能炸

openjudge1768 最大子矩阵[二维前缀和or递推|DP]

总时间限制:  1000ms 内存限制:  65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的矩阵 0 -2 -7 09 2 -6 2-4 1 -4 1-1 8 0 -2 的最大子矩阵是 9 2-4 1-1 8 这个子矩阵的大小是15. 输入 输入是一个N * N的矩阵.输入的第一行给出N (0 < N <= 100).再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给

Good Bye 2015 C. New Year and Domino 二维前缀

C. New Year and Domino They say "years are like dominoes, tumbling one after the other". But would a year fit into a grid? I don't think so. Limak is a little polar bear who loves to play. He has recently got a rectangular grid with h rows and w

计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和

题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将原矩阵顺时针旋转45°,二维前缀和预处理,然后枚举每一个可能砸到的正方形之和并取最大. 注:枚举的正方形的四个顶点必须是从原矩阵璇转过来的点,代码中用vis数组判断. #include <iostream> #include <stdio.h> #include <string.

弱校联盟10.7 I. Special Squares(二维前缀和)

题目链接: I. Special Squares There are some points and lines parellel to x-axis or y-axis on the plane. If arbitrary chosen two lines parallel to x-axis and two lines parallel to y-axis, one rectangle, or sometimes a square, will be formed. If a square i

CDOJ 1256 二维前缀和处理

昊昊喜欢运动 他NN 天内会参加MM 种运动(每种运动用一个[1,m][1,m] 的整数表示) 舍友有QQ 个问题 问昊昊第ll 天到第rr 天参加了多少种不同的运动 Input 输入两个数NN , MM (1≤N≤20001≤N≤2000 , 1≤M≤1001≤M≤100 ); 输入NN 个数aiai 表示在第i天昊昊做了第aiai 类型的运动; 输入一个数QQ (1≤Q≤1061≤Q≤106 ); 输入QQ 行 每行两个数 ll , rr (1≤l≤r≤n1≤l≤r≤n ); Output

二维前缀和 - 算法学习 - 输入输出优化

2017-08-27 11:11:38 writer:pprp 二维前缀和主要用到了容斥定理,具体实现还是有点复杂的 详见代码: /* @theme:二维前缀和 @writer:pprp @declare:用到容斥定理 @date:2017/8/27 */ #include <bits/stdc++.h> using namespace std; const int maxn = 1010; int n, m, a[maxn][maxn]; //输入优化 inline int read() {