B.Minimal Area
题意: 给定一个由 n n n个点组成的凸包,求最小三角形面积 。
分析: 凸包上相邻的 3 3 3个点必定构成最小三角形,直接暴力枚举维护面积最小值即可。
证明:
假设在红色三角形中,存在三点不相邻的一个三角形面积大于相邻三点的三角形,那么必定有 C D > A B CD>AB CD>AB,底边固定,不相邻的面积一定大于相邻的,所以相邻三点的三角形为最优解。
计算三角形面积:已知三点坐标 ( x 1 , y 1 ) , ( x 2 , y 2 ) , ( x 3 , y 3 ) (x_1,y_1),(x_2,y_2),(x_3,y_3) (x1,y1),(x2,y2),(x3,y3)
那么有 S = 1 2 ∣ x 1 y 1 1 x 2 y 2 1 x 3 y 3 1 ∣ S=\frac{1}{2}\begin{vmatrix} x_1 &y_1 &1 \\ x_2& y_2 &1 \\ x_3 & y_3 &1 \end{vmatrix} S=21∣∣∣∣∣∣x1x2x3y1y2y3111∣∣∣∣∣∣化简后得 S = 1 2 ∣ ( x 2 − x 1 ) ( y 3 − y 1 ) − ( y 2 − y 1 ) ( x 3 − x 1 ) ∣ S=\frac{1}{2}|(x2-x1)(y3-y1)-(y2-y1)(x3-x1)| S=21∣(x2−x1)(y3−y1)−(y2−y1)(x3−x1)∣
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
typedef long long LL;
int n;
LL res=4e18;
struct node{
LL x,y;
}a[N];
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y;
for(int i=1;i<=n-2;i++){
LL S=(a[i+1].x-a[i].x)*(a[i+2].y-a[i].y)-(a[i+1].y-a[i].y)*(a[i+2].x-a[i].x);
res=min(res,S);
}
res=min(res,(a[n].x-a[n-1].x)*(a[1].y-a[n-1].y)-(a[n].y-a[n-1].y)*(a[1].x-a[n-1].x));
res=min(res,(a[1].x-a[n].x)*(a[2].y-a[n].y)-(a[1].y-a[n].y)*(a[2].x-a[n].x));
cout<<res<<endl;
}
K.Video Reviews
题意: 有 n n n个人(有顺序),对 i i i来说,如果前面有 a i a_i ai个人加入,那么 i i i会加入,你可以强迫任何一个人加入,问想要加入人数达到 m m m的最小强迫次数为多少?
分析: 二分+贪心
检查时最优解就是首先说服前面的人,如果不够,那么不满足性质。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,a[N],res;
bool check(int mid){
int ans=0;
for(int i=0;i<n;i++){
if(a[i]<=ans) ans++;
else if(mid) ans++,mid--;
if(ans==m) return 1;
}
return 0;
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++) cin>>a[i];
int l=0,r=m;
while(l<=r){
int mid=l+r>>1;
if(check(mid)) r=mid-1,res=mid;
else l=mid+1;
}
cout<<res<<endl;
}