可以二分边长
然后另开两个数组,把x从小到大排序,把y从小到大排序
枚举x,可以得到正方形的长
枚举y,看看从这个y开始,往上能够到达多少个点,可以用类似队列来搞
其实发现算法的本质之后,x可以不用从小到大排序
#include <cstdio> #include <iostream> #include <algorithm> #define N 1001 #define max(x, y) ((x) > (y) ? (x) : (y)) int c, n, ans; int x[N], y[N], a[N], b[N]; inline int read() { int x = 0, f = 1; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; return x * f; } inline bool cmp1(int a, int b) { return x[a] < x[b]; } inline bool cmp2(int a, int b) { return y[a] < y[b]; } inline bool check(int len) { int i, j, k, l, r, sum; for(i = 1; i <= n; i++) { k = 1; sum = 0; l = x[a[i]]; r = l + len - 1; for(j = 1; j <= n; j++) { while(y[b[k]] - y[b[j]] + 1 <= len && k <= n) { if(l <= x[b[k]] && x[b[k]] <= r) sum++; k++; } if(sum >= c) return 1; if(l <= x[b[j]] && x[b[j]] <= r) sum--; } } return 0; } int main() { int i, l = 1, r, mid; c = read(); n = read(); for(i = 1; i <= n; i++) { x[i] = read(); y[i] = read(); r = max(r, x[i]); r = max(r, y[i]); a[i] = b[i] = i; } std::sort(a + 1, a + n + 1, cmp1); std::sort(b + 1, b + n + 1, cmp2); while(l <= r) { mid = (l + r) >> 1; if(check(mid)) ans = mid, r = mid - 1; else l = mid + 1; } printf("%d ", ans); return 0; }