ARC109D - L


平面上一開始有三個點\((0,0),(0,1),(1,0)\)形成成L形(點連續),每次操作可以將一個點改變位置,使得得到的仍然是L形。給出終止L形的位置,問移動的最小步數。

\(|x|,|y|\le 10^9,T\le 10^3\)


有若干種陰間的分類討論做法但是陽間的做法卻不好想。

CF論壇中的一位大佬分享了個clean solution:

考慮\(L\)形重心的位置,考慮每次移動重心是怎樣移動的,可以發現:重心能往8聯通方向除了跨過頂點的方向外移動一格。

於是先把L形的坐標轉化成重心的坐標,假如是8聯通,那么答案為\(\max(|X|,|Y|)\)。加上走的過程中不能跨過頂點的限制,可以發現如果\(X\neq Y\)則仍然可以走過去,如果\(X=Y\)就需要偏離一下,然后后面也可以直接走過去,代價\(+1\)


using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define x first
#define y second
pair<int,int> d[3];
ll X,Y;
void trans(){
	sort(d,d+3);
	if (d[0].x==d[1].x && d[0].y==d[2].y){
		X=d[0].x*2;
		Y=d[0].y*2;
	}
	else if (d[1].x==d[2].x && d[1].y==d[0].y){
		X=d[1].x*2-1;
		Y=d[1].y*2;
	}
	else if (d[1].x==d[0].x && d[1].y==d[2].y){
		X=d[1].x*2;
		Y=d[1].y*2-1;
	}
	else{//d[2].x==d[1].x && d[2].y==d[0].y
		X=d[2].x*2-1;
		Y=d[2].y*2-1;
	}
}
int main(){
	int T;
	scanf("%d",&T);
	while (T--){
		for (int i=0;i<3;++i)
			scanf("%lld%lld",&d[i].x,&d[i].y);
		trans();
		ll ans=max(abs(X),abs(Y));
		if (X==Y && X!=0 && X!=1)
			ans++;
		printf("%lld\n",ans);
	}
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM