Problem link
Each manhole uses 3 moves: 1 move to throw the stone on it. Plus one move to open the manhole and retrieve the coin, and 1 more move to go to a neighboring manhole. Thus, 3*num. But this is only the base case when there are 2 manholes.
Consider the case when there are 3 manholes, and let's say you start from the middle(tc = 2), after picking up the coin at this manhole #2, you have to go to left(manhole 1) or right(manhole 3) to retrieve their coins. Suppose you decide to go left first, i.e manhole #1, then after picking up the coin at 1, now you have to go to 3 in order to collect the last coin. You have to skip manhole #2 as it's empty. It will take one additional move, which is obtained by (tc-1) = 1. In this case, (tc-1) = (num-tc) = 1 as tc is at the middle. In situations where there are unequal bipartitions, tc is either more towards the left or more towards the right. If tc is more towards the left(tc <= num/2), then traverse left first and then go right, which can otherwise be calculated by (tc-1). Vice-versa is true when tc is more towards the right(tc > num/2), which is found by (num-tc). Since the objective is to find the minimum number of moves, we take the min of the two, i.e. min(tc-1, num-tc).
Remember, each manhole takes up 3 moves on its own. The extra addition term is when we change directions and skip the already visited manholes.
credit:
AKASH DAS
( from - Comment )
4 Comments
I still haven't got it. Can you explain, please.
ReplyDeleteEach manhole uses 3 moves: 1 move to throw the stone on it. Plus one move to open the manhole and retrieve the coin, and 1 more move to go to a neighbouring manhole. Thus, 3*num. But this is only the base case, when there are 2 manholes.
DeleteConsider the case when there are 3 manholes, and let's say you start from middle(tc = 2), after picking up the coin at this manhole #2, you have to go to left(manhole 1) or right(manhole 3) to retrieve their coins. Suppose you decide to go left first, i.e manhole #1, then after picking up the coin at 1, now you have to go to 3 in order to collect the last coin. You have to skip manhole #2 as it's empty. It will take one additional move, which is obtained by (tc-1) = 1. In this case, (tc-1) = (num-tc) = 1 as tc is at the middle. In situations where there are unequal bipartitions, tc is either more towards the left or more towards the right. If tc is more towards the left(tc <= num/2), then traverse left first and then go right, which can otherwise be calculated by (tc-1). Vice-versa is true when tc is more towards the right(tc > num/2), which is found by (num-tc). Since the objective is to find minimum number of moves, we take min of the two, i.e. min(tc-1, num-tc).
Remember, each manhole takes up 3 moves on its own. The extra addition term is when we change directions and skip the already visited manholes.
thanks for replie AKASH DAS
DeleteHere is a less mathematical solution:-
ReplyDelete#include
using namespace std;
#define LEFT -1
#define RIGHT 1
#define PICK_A_COIN 1
#define GO_TO_NEIGHBOURING_MANHOLE 1
int main(void)
{
int n, k, coins = 0, moves = 0;
// INPUT: No. of manholes & Index of initial manhole
cout << "INPUT: Enter number of manholes and index of initial manhole:" << endl;
cin >> n >> k;
// Translating to array index
k = k - 1;
// Creating a dynamic array
int *stones_on_manhole = new int[n];
// Initializing the array values to 1
std::fill_n(stones_on_manhole, n, 1);
// Initialization of current manhole which Nastya is on
int current_manhole = k;
// Determining the direction of movement from initial manhole
int step = (k < n / 2) ? LEFT : RIGHT;
// Collecting all the coins and counting the moves required
while (coins != n)
{
if (current_manhole == -1)
{
cout << "Reached leftmost manhole. Changing direction of traversal." << endl;
moves += k;
current_manhole = k + 1;
step = RIGHT;
cout << "Skipping previosuly visited(empty) manholes.\n";
cout << "Move Count = " << moves << endl
<< endl;
}
if (current_manhole == n)
{
cout << "Reached rightmost manhole. Changing direction of traversal." << endl;
moves += n - k - 1;
current_manhole = k - 1;
step = LEFT;
cout << "Skipping previosuly visited(empty) manholes.\n";
cout << "Move Count = " << moves << endl
<< endl;
}
cout << "Nastya is on manhole #" << current_manhole << endl;
cout << "# of stones on its cover = " << stones_on_manhole[current_manhole] << endl;
cout << "Next Move -> " << step << endl;
stones_on_manhole[current_manhole - step] += stones_on_manhole[current_manhole];
coins++;
cout << "Coins picked up = " << coins << endl;
moves += stones_on_manhole[current_manhole];
moves += PICK_A_COIN;
cout << "Move Count = " << moves << endl;
if (coins != n)
{
current_manhole += step;
moves += GO_TO_NEIGHBOURING_MANHOLE;
}
cout << endl;
}
// OUTPUT: Minimum number of moves to pick all the coins
cout << "OUTPUT:\tTotal Moves = " << moves << endl;
// Deallocation of the dynamically allocated memory
delete[] stones_on_manhole;
stones_on_manhole = NULL;
return 0;
}
If you have any doubts, Please let me know