二分答案+二维前缀和+离散化。
对于x,y进行离散化,求离散化后每个点坐标对应的前缀和。
二分求出最短长度即可
#define _CRT_SECURE_NO_WARNINGS
//#pragma GCC optimize(1)
//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
//#define N 2000005
#define M 1331
#define PII pair<int,int>
#define PIII pair<pair<int,int>,int>
#define VPII vector<PII>
#define VPIII vector<PIII>
#define inf 0x3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
const double eps = 1e-6;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define mod 1000000007
int c, n;
int sum[1005][1005]={0};
vector<int>cc;
struct scc {
int x, y;
}ss[550];
//求离散化后对应的下标
int get_id(int m) {
return lower_bound(cc.begin(), cc.end(), m) - cc.begin();
}
//判断长度p是否满足条件
bool check(int p) {
//遍历求出二维数组中每一个长度为p的正方形区域是否有满足条件的
for (int x1 = 1, x2 = 1; x2 < cc.size(); x2++) {
while (cc[x2] - cc[x1] + 1 > p) x1++;
for (int y1 = 1, y2 = 1; y2 < cc.size(); y2++) {
while (cc[y2] - cc[y1] + 1 > p) y1++;
if (sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1] >= c) return true;
}
}
return false;
}
void solve() {
cin >> c >> n;
cc.push_back(0);
for (int i = 0; i < n; i++) {
cin >> ss[i].x >> ss[i].y;
cc.push_back(ss[i].x);
cc.push_back(ss[i].y);
}
//排序+去重
sort(cc.begin(), cc.end());
cc.erase(unique(cc.begin(), cc.end()),cc.end());
//对离散化后的二维地图求出每一块的草数量
for (int i = 0; i < n; i++) {
int x = get_id(ss[i].x), y = get_id(ss[i].y);
sum[x][y]++;
}
//在上面的基础上求二维前缀和
for (int i = 1; i < cc.size(); i++) {
for (int j = 1; j < cc.size(); j++) {
sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
}
}
//二分找出答案即可
int l = 0, r = 10001;
while (l + 1 < r) {
int mid = (l + r) / 2;
if (check(mid)) r = mid;
else l = mid;
}
cout << r << "\n";
}
int main()
{
IOS;
solve();
return 0;
}