Official

F - Push and Carry Editorial by en_translator


Summary

Since the initial position of cargo \((X_B,Y_B)\) and the final position \((X_C,Y_C)\) are different, Takahashi first have to move to a position where he can push cargo, then take it to the destination. If we let the Manhattan distance between the initial positions between Takahashi and cargo be \(d_1=\lvert X_1-X_2\rvert+\lvert Y_1-Y_2\rvert\), and the Manhattan distance between the initial and final positions of cargo be \(d_2=\lvert X_2-X_3\rvert+\lvert Y_2-Y_3\rvert\), then at least \((d_1-1)+d_2=d_1+d_2-1\) actions are required.
In addition, depending on the initial relative positions of Takahshi and cargo, and relative positions between initial and final cargo, at most four more moves can be required.

We employ case analysis to handle this. The ordering of \(X\) coordinate can be one of the three \((X_i<X_j,X_i=X_j, X_i>X_j)\), so the relative position of two points can be divided into \(3\times 3-1=8\) cases. Moreover, we need to consider the relative positions for two pairs, so naively we need to consider \(64\) patterns. By appropriately enumerating the patterns and implementing the conditional branch and computation to find how many more actions than \((d_1+d_2-1)\) are required for each pattern, your code will be accepted.
In reality, we can exploit the symmetry to reduce them to \(16\) or \(10\) patterns, so that implementation is simplified, shorter time is required, and mistakes are avoided.
In this approach, the computational complexity is \(O(1)\) in most cases, so the execution time limit does not matter even with rather complex implementation. Therefore, the problem has been solved.

The description in the “details” section below focuses on simplifying proof rather than implementation, so you do not necessarily have to consider like this.

Details

The initial position of Takahashi, the initial position of the cargo, and the destination of the cargo can be simultaneously translated without changing the answer, so we can assume that the initial position of the cargo is at the origin \((0,0)\). Moreover, instead of moving the cargo along with Takahshi, one can consider that the destination moves. Therefore, the problem can be considered as follows:

Takahashi’s action is one of the following.

  • When Takahashi is at \((X, Y)\), he can move to one of \((X+1,Y),(X-1,Y),(X,Y+1)\), and \((X,Y-1)\), except for moving to the origin.
  • When he is at \(( 1,0)\), he can increase the \(X\) coordinate of the destination of the cargo by \(1\).
  • When he is at \((-1,0)\), he can decrease the \(X\) coordinate of the destination of the cargo by \(1\).
  • When he is at \((0, 1)\), he can increase the \(Y\) coordinate of the destination of the cargo by \(1\).
  • When he is at \((0,-1)\), he can decrease the \(Y\) coordinate of the destination of the cargo by \(1\).

Find the minimum number of actions required to move the destination of the cargo to the origin.

Now we consider how to solve this problem.
Depending on the ordering between each coordinate of the initial and final position of the cargo, there is a position where Takahashi must visit. For example, if \(X_2<X_3\) in the original input, then in our rephrased problem the \(X\) coordinate of the destination is positive; in order to move it to the origin, he always need to visit \((-1,0)\). If \(X_2\neq Y_2\) and \(X_3\neq Y_3\), then two points must be visited: one of \((\pm 1,0)\) and one of \((0,\pm 1)\); otherwise, one of \((\pm 1,0)\), \((0,\pm 1)\) must be visited.

The least number of actions he need to make equals (the number of moves required to visit all the points he must visit, without visiting the origin, starting from his initial position) \(+\) (the number of actions required to move the destination to the origin); conversely, these actions always let him achieve the goal. Therefore, this value is the answer. Since the number of actions required to move the destination to the origin is \(\lvert X_2-X_3\rvert+\lvert Y_2-Y_3\rvert\) times, all that left is to find the number of moves required to visit all the points he must visit, without visiting the origin, starting from his initial position.

i) If he must visit one point

In most cases, he can move from \((X_1-X_2,Y_1-Y_2)\) to the point \((X',Y')\) that he wants to visit \(\bigl(\)\((X',Y')\) is one of \((\pm 1,0)\), \((0,\pm 1)\)\(\bigr)\) without visiting the origin in \(\lvert (X_1-X_2)-X'\rvert+\lvert (Y_1-Y_2)-Y'\rvert\) moves. The only exception is when \(X_1-X_2=X'=0\) and the signs of \((Y_1-Y_2)\) and \(Y'\) are different (note that in this case, the constraints guarantee that \(Y_!-Y_2\neq 0\) and \(Y'\neq 0\)), or when the opposite holds, i.e. \(Y_1-Y_2=Y'=0\) and the signs of \((X_1-X_2)\) and \(X'\) are different. In this case, in order to detour the origin, two or more moves in the \(X\) direction (for the former case) or the \(Y\) direction (for the latter case) are required. Therefore, the number of moves for this is \(\lvert (X_1-X_2)-X'\rvert+\lvert (Y_1-Y_2)-Y'\rvert+2\).

ii) If he must visit two points One of the two points are chosen from \((\pm 1,0)\), and the other from \((0, \pm 1)\), so he can travel between any of the two with two moves (and conversely, at least two moves are required.) Therefore, it is sufficient for Takahashi to choose the nearer of the two points to visit, and then spend two more actions to move to the other. As we have already found the number of moves required to travel from the initial point to each point, it is sufficient to compare them and add two (the additional moves required to move to the other point) to the smaller of them.

Therefore, the answer has been found for all possible cases.

Sample code in C++ (according to the approach described in the details section):

#include <bits/stdc++.h>
using namespace std;

long long dist(long long x1,long long y1,long long x2,long long y2){
	if((x1==0)&&(x2==0)&&(signbit(y1)!=signbit(y2)))return abs(y1-y2)+2;
	if((y1==0)&&(y2==0)&&(signbit(x1)!=signbit(x2)))return abs(x1-x2)+2;
	return abs(x1-x2)+abs(y1-y2);
}

int main() {
	long long x[3],y[3];
	int idx=0;
	long long vis[2][2];

	cin>>x[0]>>y[0]>>x[1]>>y[1]>>x[2]>>y[2];
	x[0]-=x[1],y[0]-=y[1];
	x[2]-=x[1],y[2]-=y[1];

	if(x[2]>0){vis[idx][0]=-1,vis[idx][1]=0,idx++;}
	if(x[2]<0){vis[idx][0]=1,vis[idx][1]=0,idx++;}
	if(y[2]>0){vis[idx][0]=0,vis[idx][1]=-1,idx++;}
	if(y[2]<0){vis[idx][0]=0,vis[idx][1]=1,idx++;}

	long long ans=abs(x[2])+abs(y[2]);
	if(idx==1)ans+=dist(x[0],y[0],vis[0][0],vis[0][1]);
	else ans+=min(dist(x[0],y[0],vis[0][0],vis[0][1]),dist(x[0],y[0],vis[1][0],vis[1][1]))+2;

	cout<<ans<<endl;
	return 0;
}

posted:
last update: