acm-(贪心、思维)Educational Codeforces Round 99 (Rated for Div. 2) E. Four Points

题面
传送门
本题考虑枚举每个点到达正方形的位置(左上角、右上角、左下角、右下角),总共有 4 ! 4! 4!种可能,对于每种可能而言,假设去左上角、右上角、左下角、右下角的点分别用 1 、 2 、 3 、 4 1、2、3、4 1234表示,先分别考虑 x 、 y x、y xy的贡献,设 x 1 ′ = m i n { x 1 , x 3 } , x 2 ′ = m a x { x 1 , x 3 } , x 3 ′ = m i n { x 2 , x 4 } , x 4 ′ = m a x { x 2 , x 4 } x_1'=min\{x_1,x_3\},x_2'=max\{x_1,x_3\},x_3'=min\{x_2,x_4\},x_4'=max\{x_2,x_4\} x1=min{x1,x3},x2=max{x1,x3},x3=min{x2,x4},x4=max{x2,x4},我们发现若 x 1 , x 3 x_1,x_3 x1,x3到达 [ x 1 ′ , x 2 ′ ] [x_1',x_2'] [x1,x2]中的无论哪个位置,贡献为 x 2 ′ − x 1 ′ x_2'-x_1' x2x1 x 2 , x 4 x_2,x_4 x2,x4则无论到达 [ x 3 ′ , x 4 ′ ] [x_3',x_4'] [x3,x4]中的哪个位置贡献为 x 4 ′ − x 3 ′ x_4'-x_3' x4x3,因此我们正方形上下边的长度的区间范围是 [ m a x { x 3 ′ − x 2 ′ , 0 } , m a x { x 4 ′ − x 1 ′ , 0 } ] [max\{x_3'-x_2',0\},max\{x_4'-x_1',0\}] [max{x3x2,0},max{x4x1,0}],简写为 [ l x , r x ] [lx,rx] [lx,rx],在这个范围中我们发现点在移动的过程中 x x x轴层次上产生的贡献恒定为 v a l x = x 4 ′ − x 3 ′ + x 2 ′ − x 1 ′ valx=x_4'-x_3'+x_2'-x_1' valx=x4x3+x2x1。不过有个特殊情况是,若 x 4 ′ < x 1 ′ x_4'<x_1' x4<x1,那么 x 1 , x 3 x_1,x_3 x1,x3到达 [ x 1 ′ , x 2 ′ ] [x_1',x_2'] [x1,x2]的同时 x 2 , x 4 x_2,x_4 x2,x4无法到达 [ x 2 ′ , x 3 ′ ] [x_2',x_3'] [x2,x3],此时容易发现有 l x = r x = 0 , v a l x = x 4 − x 1 + x 3 − x 2 lx=rx=0,valx=x_4-x_1+x_3-x_2 lx=rx=0,valx=x4x1+x3x2

同样地,利用上述方法可以求出 l y , r y , v a l y ly,ry,valy ly,ry,valy

如果题目让求一个矩形的话,本题已经做完了,答案就是 v a l y + v a l x valy+valx valy+valx,不过本题要求必须是正方形,因此得让两边的长度相同,我们发现若 [ l x , r x ] [lx,rx] [lx,rx] [ l y , r y ] [ly,ry] [ly,ry]存在交集,说明两个维度上可以通过适当调节使得正方形边长相等,且 v a l x , v a l y valx,valy valx,valy维持不变。不过当两个区间不存在交集的时候,我们一定会改变某一个维度的边长来使得跟另一个维度的边长相等,假设 r y < l x ry<lx ry<lx,那么我们只需要让 y y y轴上的边长变成 l x lx lx即可,这样的话需要 v a l y + = 2 ( l x − r y ) valy+=2(lx-ry) valy+=2(lxry),也就是价值会多出一部分,另一个对称情况是 r x < l y rx<ly rx<ly,这样需要 v a l x + = 2 ( l y − r x ) valx+=2(ly-rx) valx+=2(lyrx)

struct Point{
	ll x,y;
};
int main(){
	int t=rd();
	while(t--){
		Point a[4];
		FOR(i,0,4)a[i].x=rd(),a[i].y=rd();
		int b[4]={0,1,2,3};
		ll ans=INF;
		do{
			ll x1=min(a[b[0]].x,a[b[2]].x),x2=max(a[b[0]].x,a[b[2]].x),x3=min(a[b[1]].x,a[b[3]].x),x4=max(a[b[1]].x,a[b[3]].x);
			ll y1=min(a[b[2]].y,a[b[3]].y),y2=max(a[b[2]].y,a[b[3]].y),y3=min(a[b[0]].y,a[b[1]].y),y4=max(a[b[0]].y,a[b[1]].y);
			ll lx=0,rx=0,ly,ry,valx,valy;
			if(x4<x1){
				valx=x1-x4+x2-x3;
				lx=rx=0;
			}else{
				valx=x4-x3+x2-x1;
				lx=max(x3-x2,0ll);
				rx=x4-x1;
			}
			if(y4<y1){
				valy=y1-y4+y2-y3;
				ly=ry=0;
			}else{
				valy=y4-y3+y2-y1;
				ly=max(y3-y2,0ll);
				ry=y4-y1;
			}
			if(lx<=ry && rx>=ly)ans=min(ans,valx+valy);
			else if(rx<ly)ans=min(ans,valx+valy+2*(ly-rx));
			else ans=min(ans,valx+valy+2*(lx-ry));
		}while(next_permutation(b,b+4));
		printf("%lld\n",ans);
	}
} 
  • 0
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页
评论

打赏作者

&*^*&

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值