https://www.acwing.com/problem/content/123/
对坐标离散化之后暴力二分枚举边长,然后尺取验证,复杂度(O(n^2logn))。
WA了1发因为y坐标没有清空。尺取的那个二分开头是没必要的,还容易错(当没有把坐标偏移到从(1,1)开始就不能这样二分找初始位置)。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int c, n;
int x[505];
int y[505];
int xx[505];
int yy[505];
int sum[505][505];
int xxtop, yytop;
bool check(int len) {
int prex = 0, prey = 0;
//int curx = (upper_bound(xx + 1, xx + 1 + xxtop, len) - xx) - 1;
//int cury = (upper_bound(yy + 1, yy + 1 + yytop, len) - yy) - 1;
int curx = 1;
int cury = 1;
int tmpy = cury;
//printf("len=%d x=%d y=%d
", len, x[curx], y[cury]);
//printf("len=%d x=%d y=%d
", len, curx, cury);
while(curx <= xxtop - 1) {
while(xx[curx] - xx[prex + 1] >= len)
++prex;
prey = 0;
cury = tmpy;
while(cury <= yytop - 1) {
while(yy[cury] - yy[prey + 1] >= len)
++prey;
//printf("[%d,%d][%d,%d]
",prex+1,curx,prey+1,cury);
//printf("[%d,%d][%d,%d]
",xx[prex+1],xx[curx],yy[prey+1],yy[cury]);
if(sum[curx][cury] - sum[prex][cury] - sum[curx][prey] + sum[prex][prey] >= c) {
//puts("TRUE");
/*printf("prex=%d
",prex+1);
printf("prey=%d
",prey+1);
printf("curx=%d
",curx);
printf("cury=%d
",cury);
printf("prex=%d
",xx[prex+1]);
printf("prey=%d
",yy[prey+1]);
printf("curx=%d
",xx[curx]);
printf("cury=%d
",yy[cury]);*/
return true;
}
++cury;
}
++curx;
}
//puts("FALSE");
return false;
}
int bs() {
int l = 1, r = 10001, m;
while(1) {
m = (l + r) >> 1;
if(l == m) {
if(check(l))
return l;
return r;
}
if(check(m))
r = m;
else
l = m + 1;
}
}
int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
scanf("%d%d", &c, &n);
int minx = 10005, miny = 10005;
for(int i = 1; i <= n; ++i) {
scanf("%d", &x[i]);
scanf("%d", &y[i]);
minx = min(minx, x[i]);
miny = min(miny, y[i]);
}
for(int i = 1; i <= n; ++i) {
xx[i] = x[i] = x[i] - minx + 1;
yy[i] = y[i] = y[i] - miny + 1;
}
xx[n + 1] = x[n + 1] = 10005;
yy[n + 1] = y[n + 1] = 10005;
sort(xx + 1, xx + 1 + n + 1);
sort(yy + 1, yy + 1 + n + 1);
xxtop = unique(xx + 1, xx + 1 + n + 1) - (xx + 1);
yytop = unique(yy + 1, yy + 1 + n + 1) - (yy + 1);
for(int i = 1; i <= n + 1; ++i) {
x[i] = lower_bound(xx + 1, xx + 1 + xxtop, x[i]) - xx;
y[i] = lower_bound(yy + 1, yy + 1 + yytop, y[i]) - yy;
//printf("x=%d y=%d
", x[i], y[i]);
if(i <= n)
sum[x[i]][y[i]]++;
}
for(int i = 1; i <= xxtop; ++i) {
for(int j = 1; j <= yytop; ++j) {
sum[i][j] += (sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1]);
//printf("%d", sum[i][j] - sum[i - 1][j] - sum[i][j - 1] + sum[i - 1][j - 1]);
//printf("%d", sum[i][j]);
}
//puts("");
}
printf("%d
", bs());
}