题目链接:https://www.luogu.org/problemnew/show/P1578
障碍点个数S
最坏时间复杂度O(S^2) ,实际运行中因为剪枝优化会快很多。
障碍点可以在边界上。
#include <bits/stdc++.h>
#define ll long long
#define mp make_pair
#define pb push_back
#define sec second
#define fir first
#define rep(i,a,b) for(int i = (a); i <= (b); i++)
#define per(i,a,b) for(int i = (a); i >= (b); i--)
#define all(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define pii pair<int,int>
using namespace std;
vector<pii> s;
int maxx = 0;
bool cmp(pii x, pii y) {
return x.sec<y.sec;
}
int main() {
//freopen("a.txt","r",stdin);
ios::sync_with_stdio(0);
int n, m, k;
cin>>n>>m>>k;
rep(i, 1, k) {
int x, y;
cin>>x>>y;
s.pb(mp(x,y));
}
s.pb(mp(0,0)); //将四个角设置为障碍点
s.pb(mp(n,m));
s.pb(mp(0,m));
s.pb(mp(n,0));
sort(all(s),cmp);
rep(i, 0, SZ(s)-2)
maxx = max(maxx,n*(s[i+1].sec-s[i].sec)); //特判左右边界均无障碍点
sort(all(s));
s.erase(unique(all(s)),s.end());
rep(i, 0, SZ(s)-1) { //枚举左边界障碍点
int up=m,down=0,t=n-s[i].fir;
rep(j, i+1, SZ(s)-1) {
maxx = max(maxx,(up-down)*(s[j].fir-s[i].fir));
if(t*(up-down)<=maxx) break; //最优化剪枝
if(s[j].sec==s[i].sec) break;
if(s[j].sec>s[i].sec) up = min(up,s[j].sec);
else down = max(down,s[j].sec);
}
}
per(i, SZ(s)-1, 0) { //枚举右边界障碍点
int up=m,down=0,t=s[i].fir;
per(j, i-1, 0) {
maxx = max(maxx,(up-down)*(s[i].fir-s[j].fir));
if(t*(up-down)<=maxx) break; //最优化剪枝
if(s[j].sec==s[i].sec) break;
if(s[j].sec>s[i].sec) up = min(up,s[j].sec);
else down = max(down,s[j].sec);
}
}
cout<<maxx;
return 0;
}