atcoder.jp/contests/ab…
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
struct P{
ll px,py;
};
// 向量加法
P operator+(const P& a1, const P& a2) {
return P{ a1.px + a2.px, a1.py + a2.py };
}
// 向量减法
P operator-(const P& a1, const P& a2) {
return { a1.px - a2.px, a1.py - a2.py };
}
bool operator<(const P& a1, const P& a2) {
if (a1.px < a2.px) return true;
if (a1.px > a2.px) return false;
if (a1.py < a2.py) return true;
return false;
}long long crs(P p1, P p2) {
return p1.px * p2.py - p1.py * p2.px;
}
int main(){
int n;cin>>n;
vector<P>pts(n);
for(int i=0;i<n;i++){cin>>pts[i].px>>pts[i].py;
}ll s=0;
for(int i=2;i<n;i++){
s+=abs(crs(pts[i-1]-pts[0],pts[i]-pts[0]));
}ll res=8e18;
ll e=0;
int q=1;
for(int p=0;p<n;p++){
while(4*e<s){
e+=abs(crs(pts[q]-pts[p],pts[(q+1)%n]-pts[p]));
q=(q+1)%n;
res=min(res,abs(4*e-s));
}e-=abs(crs(pts[p]-pts[q],pts[(p+1)%n]-pts[q]));
res=min(res,abs(4*e-s));}
cout<<res;}
1. 对象是凸多边形(点按顺序排列)
2. 固定一个端点 p,另一个端点 q 往右移
3. 面积随 q 右移单调递增(只增不减)
4. 我们要找面积最接近某个目标值(S/4)
满足单调性 → 双指针不会回退 → 滑动窗口成立。