很好的一道离散化题目
坐标范围在
,那么二维数组肯定存不下,况且用二维前缀和枚举横纵坐标也是
,超时
但是坐标个数最多只有
个,也就是说不同的数最多也只有
个,离散化后最关键的一个问题是如何枚举:正常的做法就是枚举横纵坐标
,但是会超时,这里使用类似于双指针的方法来模拟:
总代码:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;
int n, m, k;
vector<int> num;
int sum[1010][1010];
int get(int x){
return lower_bound(num.begin(), num.end(), x) - num.begin();
}
bool check(int x){
for(int i = 1; i <= k; i ++){
int pos1 = i;
while(pos1 <= k && num[pos1] - num[i] + 1 <= x) pos1 ++;
for(int j = 1; j <= k; j ++){
int pos2 = j;
while(pos2 <= k && num[pos2] - num[j] + 1 <= x) pos2 ++;
int now_sum = sum[pos1 - 1][pos2 - 1] - sum[i - 1][pos2 - 1] - sum[pos1 - 1][j - 1] + sum[i - 1][j - 1];
if(now_sum >= m) return true;
}
}
return false;
}
void solve(){
cin >> m >> n;
num.push_back(0);
vector<pair<int, int> > a;
for(int i = 1; i <= n; i ++){
int x, y; cin >> x >> y;
num.push_back(x);
num.push_back(y);
a.push_back({x, y});
}
sort(num.begin(), num.end());
num.erase(unique(num.begin(), num.end()), num.end());
for(int i = 0; i < (int)a.size(); i ++){
int x = get(a[i].first), y = get(a[i].second);
sum[x][y] ++;
}
k = (int)num.size() - 1;
for(int i = 1; i <= k; i ++){
for(int j = 1; j <= k; j ++) sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
}
int l = 1, r = 10000, ans = 10000;
while(l <= r){
int mid = (l + r) / 2;
if(check(mid)){
ans = mid;
r = mid - 1;
}
else l = mid + 1;
}
cout << ans << endl;
return ;
}
signed main(){
HelloWorld;
int tt = 1;
while(tt --) solve();
return 0;
}



京公网安备 11010502036488号