【算法】【几何】

0 阅读1分钟

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;}
	

图片.png

图片.png

1. 对象是凸多边形(点按顺序排列)

2. 固定一个端点 p,另一个端点 q 往右移

3. 面积随 q 右移单调递增(只增不减)

4. 我们要找面积最接近某个目标值(S/4)

满足单调性 → 双指针不会回退 → 滑动窗口成立。