这里补充一下子集的理解:
这个题目的关键就是将问题转化成三分,如何转化这个模型呢?
分为几种情况来考虑
Δx 和 Δy 的值都增大的时候,面积 S 值一定单调递增
Δx 和 Δy 的值都减小的时候,面积 S 值一定单调递减
Δx 和 Δy 的值一增一减的时候,就要判断它的情况。
这时候就要考虑 Δx 和 Δy 的变化率问题,如果 Δx 减小的变化率大,则面积 S 递减,
但 Δx 减小的变化率小,那么面积 S 递增,那么一定会有最小面积在这两段中间,所以就可以三分来找答案。(其实不用考虑上面的详细情况,因为这个题目求得就是最小值,而且当 Δx 或 Δy 增大、减小到某个值后又会与之前的面积 S 相同,所以可以无脑三分)
参考代码
#include<stdio.h>
int n;
double min(double a,double b){
return a>=b?b:a;
}
double max(double a,double b){
return a>=b?a:b;
}
struct node
{
double x;
double y;
char d;
}a[100010];
double f(double t){
double Mx = -1e18,My = -1e18,mx = 1e18,my = 1e18; //上下左右的点
for(int i = 1;i <= n;i++){
double x = a[i].x,y = a[i].y;
if(a[i].d == 'U') y += t;
else if(a[i].d == 'D') y -= t;
else if(a[i].d == 'L') x -= t;
else if(a[i].d == 'R') x += t;
Mx = max(Mx,x);
mx = min(mx,x);
My = max(My,y);
my = min(my,y);
}
// printf("%lf %lf",Mx,mx);
return (Mx - mx)*(My - my);
}
int main(){
scanf("%d",&n);
for(int i = 1;i <= n;i++) scanf("%lf %lf %c",&a[i].x,&a[i].y,&a[i].d);
// for(int i = 1;i <= n;i++) printf("\n%.6f,%.6f %c",a[i].x,a[i].y,a[i].d);
double r = 1e12,l = 0; //枚举范围就是 0 - 1e12
double mmin = 1e18; //初始化最小值
double ml,mr,ansl,ansr;
for(int i = 1;i <= 300;i++){
ml = l+(r-l)/3,mr = l+2*(r-l)/3;
ansl = f(ml);
ansr = f(mr);
if(ansl > ansr) l = ml;
else r = mr;
mmin = min(ansl,mmin),mmin = min(ansr,mmin);
}
printf("%.6lf\n",mmin);
return 0;
}