abc075d <暴力枚举 / 枚举+离散化+二维前缀和>

发布时间 2023-07-11 10:26:21作者: O2iginal

D - Axis-Parallel Rectangle

// https://atcoder.jp/contests/abc075/tasks/abc075_d
//  <暴力枚举 / 枚举+离散化+二维前缀和>
// 本代码为完全暴力枚举, N^4 枚举所有矩形, N 计算矩形内点数;
// 实际上, 计算矩形内点数可通过二维前缀和 O(1)得到,
//    参考 : https://www.bilibili.com/read/cv24491823
// 注意 : 矩形顶点不能仅枚举已有顶点, 而需要离散化枚举所有出现过的数值组合 !
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
using LL = long long;
const int INF = 0x3f3f3f3f;

struct Node
{
    LL x, y;
} a[55];

void solv()
{
    int n, k;
    cin >> n >> k;
    int x, y;
    vector<LL> vx, vy;
    for (int i = 1; i <= n; i++)
    {
        cin >> x >> y;
        a[i] = {x, y};
        vx.push_back(x);
        vy.push_back(y);
    }
    LL ans = 4.1e18;
    sort(vx.begin(), vx.end());
    sort(vy.begin(), vy.end());
    for (int i1 = 0; i1 < vx.size(); i1++)
        for (int i2 = i1 + 1; i2 < vx.size(); i2++)
            for (int j1 = 0; j1 < vy.size(); j1++)
                for (int j2 = j1 + 1; j2 < vy.size(); j2++)
                {
                    LL x1 = vx[i1], x2 = vx[i2], y1 = vy[j1], y2 = vy[j2];
                    int cnt = 0;
                    for (int i = 1; i <= n; i++)
                        if (a[i].x >= x1 && a[i].x <= x2 && a[i].y >= y1 && a[i].y <= y2)
                            cnt++;
                    if (cnt >= k) ans = min(ans, (x2 - x1) * (y2 - y1));
                }
    cout << ans << endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T = 1;
    // cin >> T;
    while (T--)
    {
        solv();
    }
    return 0;
}