Google Kick Start Archive — Round G 2020 problems

Overview

Thank you for participating in Kick Start 2020 Round G.


Cast

Kick_Start: Written by Changyu Zhu and prepared by Sherry Wu.

Maximum Coins: Written by Swapnil Gupta and prepared by Anson Ho.

Combination Lock: Written by Pablo Heiber and prepared by Swapnil Gupta.

Merge Cards: Written by Yossi Matsumoto and prepared by Nikhil Hassija.

Solutions, other problem preparation, reviews and contest monitoring by Akul Siddalingaswamy, Anson Ho, Anushi Maheshwari, Bartosz Kostka, Bohdan Pryshchenko, Cristhian Bonilha, Devanshu Agarwal, Diksha Saxena, Gagan Madan, Jared Gillespie, Jayant Sharma, Jie Zhou, Kevin Tran, Krists Boitmanis, Lalit Kundu, Lizzie Sapiro, Marcin Wawerka, Nikhil Hassija, Phil Sun, Raihat Zaman Neloy, Ruoyu Zhang, Sadia Atique, Sai Surya Upadrasta, Seunghyun Jo, Sherry Wu, Shweta Karwa, Swapnil Gupta, Teja Vardhan Reddy Dasannagari, Tejendra Patel, Wajeb Saab, Wei Zhou, and Yossi Matsumoto.

Analysis authors:

  • Kick_Start: Kashish Bansal
  • Maximum Coins: Swapnil Gupta
  • Combination Lock: Swapnil Gupta
  • Merge Cards: Anson Ho

A. Kick_Start

Problem

Ksenia is very fond of reading so she kicks off each day by reading a fragment from her favourite book before starting with the rest of her morning routine. A fragment is simply a substring of the text. Ksenia is somewhat superstitious and believes that her day will be lucky if the fragment she reads starts with the string KICK, then goes on with 0 or more characters, and eventually ends with the string START, even if the overall fragment makes little sense.

Given the text of the book, count the number of different lucky fragments that Ksenia can read before the book gets old and she needs to buy another one. Two fragments are considered to be different if they start or end at different positions in the text, even if the fragments read the same. Also note that different lucky fragments may overlap.

Input

The first line of the input gives the number of test cases T. T lines follow, each containing a single string S consisting of upper case English letters only.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the number of different lucky fragments in the text of this test case.

Limits

Memory limit: 1 GB.
1 ≤ T ≤ 100.
S consists of upper-case English letters only.

Test Set 1

Time limit: 20 seconds.
1 ≤ |S| ≤ 1000.

Test Set 2

Time limit: 40 seconds.
1 ≤ |S| ≤ 105.

Sample

Sample Input
content_copy Copied!
3
AKICKSTARTPROBLEMNAMEDKICKSTART
STARTUNLUCKYKICK
KICKXKICKXSTARTXKICKXSTART
Sample Output
content_copy Copied!
Case #1: 3
Case #2: 0
Case #3: 5

There are three lucky fragments in the first test case, namely, KICKSTARTPROBLEMNAMEDKICKSTART and two occurrences of KICKSTART. The text in the second test case has no lucky fragments at all.

B. Maximum Coins

Problem

Mike has a square matrix with N rows and N columns. Cell (i,j) denotes the cell present at row i and column j. Cell (1,1) denotes the top left corner of the matrix. Each cell has some amount of coins associated with it and Mike can collect them only if he visits that cell. Ci,j represents the number of coins in cell with row i and column j. From a cell (i,j), Mike can decide to go to cell (i+1,j+1) or cell (i-1,j-1), as long as the cell lies within the boundaries of the matrix and has not been visited yet. He can choose to start the journey from any cell and choose to stop at any point. Mike wants to maximize the number of coins he can collect. Please help him determine the maximum number of coins he can collect.

Input

The first line of the input gives the number of test cases, T. T test cases follow. Each test case begins with a line containing the integer N. The next N lines contain N integers each. The j-th integer in the i-th line represents the number of coins Ci,j in cell (i,j).

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the maximum number of coins Mike can collect.

Limits

Time limit: 20 seconds.
Memory limit: 1 GB.
1 ≤ T ≤ 100.
0 ≤ Ci,j ≤ 107.

Test Set 1

1 ≤ N ≤ 100.

Test Set 2

1 ≤ N ≤ 103 in at most 10 cases.
1 ≤ N ≤ 100 in all other cases.

Sample

Sample Input
content_copy Copied!
2
3
1 2 5
3 6 1
12 2 7
5
0 0 0 0 0
1 1 1 1 0
2 2 2 8 0
1 1 1 0 0
0 0 0 0 0
Sample Output
content_copy Copied!
Case #1: 14
Case #2: 9

In Sample Case #1, the maximum number of coins collected can be 14, if Mike follows this path: (1,1) -> (2,2) -> (3,3)

In Sample Case #2, the maximum number of coins collected can be 9, if Mike follows this path: (2,3) -> (3,4).

C. Combination Lock

Problem

A combination lock has W wheels, each of which has the integer values 1 through N on it, in ascending order.

At any moment, each wheel shows a specific value on it. Xi is the initial value shown on the i-th wheel.

You can use a single move to change a wheel from showing the value X to showing either X+1 or X-1, wrapping around between 1 and N. For example, if a wheel currently shows the value 1, in one move you can change its value to 2 or N.

Given all wheels' initial values, what is the minimum number of moves to get all wheels to show the same value?

Input

The first line of the input gives the number of test cases, T. T test cases follow.

The first line of each test case contains the two integers W and N.

The second line contains W integers. The i-th integer is Xi.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the minimum number of moves to get all wheels to show the same value.

Limits

Time limit: 40 seconds.
Memory limit: 1 GB.
1 ≤ T ≤ 100.
1 ≤ XiN.

Test Set 1

1 ≤ W ≤ 1000.
2 ≤ N ≤ 1000.

Test Set 2

1 ≤ W ≤ 1000.
2 ≤ N ≤ 109.

Test Set 3

1 ≤ W ≤ 105.
2 ≤ N ≤ 109.

Sample

Sample Input
content_copy Copied!
2
3 5
2 3 4
4 10
2 9 3 8
Sample Output
content_copy Copied!
Case #1: 2
Case #2: 8

In Sample Case #1, the best solution is to get all wheels to show value 3, which would take a total of 2 moves: the first wheel would move once (from value 2 to value 3), the second wheel would not move (it already shows value 3), and the third wheel would move once (from value 4 to value 3).

For reference, it would take 5 moves to get all wheels to show value 1, 3 moves to get all wheels to show value 2, 3 moves to get all wheels to show value 4, and 5 moves to get all wheels to show value 5.

In Sample Case #2, the best solutions are to get all wheels to show either value 1, 2, 9 or 10, which would take a total of 8 moves.

D. Merge Cards

Problem

Panko is playing a game with N cards laid out in a row. The i-th card has the integer Ai written on it.

The game is played in N - 1 rounds. During each round Panko will pick an adjacent pair of cards and merge them. Suppose that the cards have the integers X and Y written on them. To merge two cards, Panko creates a new card with X + Y written on it. He then removes the two original cards from the row and places the new card in their old position. Finally Panko receives X + Y points for the merge. During each round Panko will pick a pair of adjacent cards uniformly at random amongst the set of all available adjacent pairs.

After all N - 1 rounds, Panko's total score is the sum of points he received for each merge. What is the expected value of Panko's total score at the end of the game?

Input

The first line of the input gives the number of test cases, T. T test cases follow. Each test case begins with a line containing the integer N. A second line follows containing N integers, describing the initial row of cards. The i-th integer is Ai.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the expected total score at the end of the game.

y will be considered correct if it is within an absolute or relative error of 10-6 of the correct answer. See the FAQ for an explanation of what that means, and what formats of real numbers we accept.

Limits

Time limit: 40 seconds.
Memory limit: 1 GB.
1 ≤ T ≤ 100.
1 ≤ Ai ≤ 109 for all i.

Test Set 1

2 ≤ N ≤ 9.

Test Set 2

2 ≤ N ≤ 100.

Test Set 3

2 ≤ N ≤ 5000.

Sample

Sample Input
content_copy Copied!
2
3
2 1 10
5
19 3 78 2 31
Sample Output
content_copy Copied!
Case #1: 20.000000
Case #2: 352.33333333

In sample case #1, N = 3. The initial row of cards is [2, 1, 10]. In the first round, Panko has two choices, of which he will choose one at random.

  • If Panko merges the first pair (2, 1), then the row of cards becomes [3, 10], adding 2 + 1 = 3 points to his total score. In the second round, there is only one pair remaining (3, 10). If he merges them, the row of cards becomes [13], adding 3 + 10 = 13 points to his total score. Panko ends the game with 3 + 13 = 16 points.
  • If Panko merges the second pair (1, 10), then the row of cards becomes [2, 11], adding 1 + 10 = 11 points to his total score. In the second round, there is only one pair remaining (2, 11). If he merges them, the row of cards becomes [13], adding 2 + 11 = 13 points to his total score. Panko ends the game with 11 + 13 = 24 points.
Thus, the expected number of points Panko ends the game with is (16 + 24)/2 = 20.

In sample case #2, N = 5. The initial row of cards is [19, 3, 78, 2, 31]. There are too many possibilities to list here, so we will only go through one possible game:

  • In the first round, if Panko merges the pair (78, 2), then the row of cards becomes [19, 3, 80, 31], adding 78 + 2 = 80 to his score.
  • In the second round, if Panko merges the pair (80, 31), then the row of cards becomes [19, 3, 111], adding 80 + 31 = 111 to his score.
  • In the third round, if Panko merges the pair (19, 3), then the row of cards becomes [22, 111], adding 19 + 3 = 22 to his score.
  • In the fourth round, if Panko merges the pair (22, 111), then the row of cards becomes [133], adding 22 + 111 = 133 to his score.
At the end of the game explained above, Panko's total score is 80 + 111 + 22 + 133 = 346.

Analysis — A. Kick_Start

The given problem statement can be rephrased as counting the number of substrings (fragments) which begin with string 'KICK' and end with string 'START'. Another thing to note is that a substring starting with 'KICK' can form multiple lucky fragments ending at different 'START'. For example, consider the string 'KICKSTARTSTART'. This string contains two lucky fragments, first being 'KICKSTART' and second being 'KICKSTARTSTART'.

Test Set 1

For a substring to be considered as a lucky fragment, we can check if it starts with 'KICK' and ends with 'START'. For every substring from i-th to j-th index, where 0 ≤ i < j < N, we can check if the substring begins with 'KICK' by comparing whether i-th index is equal to 'K', (i+1)-th index is equal to 'I', ... , (i+3)-th index is equal to 'K'. Similarly we can check if the substring ends with 'START' by comparing whether (j-4)-th index is equal to 'S', (j-3)-th index is equal to 'T', ... , j-th index is equal to 'T'. Note that we only check the characters if the indices are within the bounds of the substring. Hence, it takes constant number of operations to check whether a substring is lucky fragment or not. In total, we have O(N2) substrings to check. Therefore, total time complexity for the approach is O(N2).

Another solution could be to use two loops iterating over the string. Outer loop is used to scan the string for 'KICK'. Whenever 'KICK' is encountered, we use the inner loop to scan the remaining string i.e. substring to the right of 'KICK' to count the occurrences of string 'START'. We repeat this for every 'KICK' encountered using the outer loop and keep summing up the count of occurrences of string 'START' to get the total number of lucky fragments. Rationale is that every 'START' encountered can be paired up with the 'KICK' found using outer loop to create a lucky fragment for Ksenia.
As we iterate over the string using two loops, the overall time complexity for this solution is O(N2).

Test Set 2

We take a single pass over the string. During this pass, we perform following two checks:

  • If we encounter string 'KICK', we increase a counter, let it be X.
  • If we encounter string 'START', we add the number of 'KICK' encountered till now to the final answer, in other words add the current value of X to the final answer.

Rationale is that every 'START' we encounter can be paired up with any 'KICK' encountered before to create a lucky fragment.
Time complexity is O(N) for the solution as we take a single pass over the string.

Test Data
info We recommend that you practice debugging solutions without looking at the test data.

Analysis — B. Maximum Coins

Terminology: In what follows, when we refer to a diagonal starting from (x, y), we mean all cells (p, q) such that x - y = p - q. Only cells satisfying these conditions are considered, because Mike can only move diagonally.

Test Set 1

Mike is allowed to go from cell (i,j) to cell (i+1,j+1) or to cell (i-1,j-1). We can consider each possible starting point and try calculating the value of each possible path Mike can traverse. Initialize the answer as 0. For each starting cell (i,j), Mike can either go diagonally upwards or diagonally downwards. First consider all the paths which start at cell (i,j) and end diagonally above it. We keep on adding the value of coins by traversing upwards diagonally and updating the answer. Similarly, we consider all paths which start at cell (i,j) and end diagonally below it and update the answer. Each path can contain at most O(N) elements. Thus, it takes O(N) time for each starting position. There can be O(N2) starting positions. Thus, the overall complexity of the solution is O(N3).

Sample Code(C++)

int GetMaximumCoins(const vector< vector< int > >& coins) {
  int answer = 0;
  for(int i = 0; i < coins.size(); i++) {
    for(int j = 0; j < coins[0].size(); j++) {
    int currx = i, curry = j, currval = 0;
    // Go above.
    while(currx >= 0 and curry >= 0) {
      currval += coins[currx][curry];
      answer = max(answer, currval);
      currx--;
      curry--;
    }
    currx = i;
    curry = j;
    currval = 0;
    // Go below.
    while(currx < coins.size() and curry < coins[0].size()) {
      currval += coins[currx][curry];
      answer = max(answer, currval);
      currx++;
      curry++;
    }
   }
  }
  return answer;
}

Test Set 2

An important observation here is that all the numbers are positive. Thus, it is always optimal to collect the coins for each cell present on a particular diagonal instead of choosing some of the cells on the diagonal. This can be done by starting on the top left of each diagonal and traversing down and adding the coins collected. For each diagonal it would take O(N) time to calculate the coins present in that diagonal. There are O(N) diagonals present in the matrix. Thus, the overall time complexity of the solution is O(N2).

Sample Code(C++)


long long int GetDiagonalSum(const vector< vector< int > >& coins, int i, int j) {
   long long int currval = 0;
   int currx = i, curry = j;
   while(currx < coins.size() 0 && curry < coins[0].size()) {
     currval += coins[currx][curry];
     currx++;
     curry++;
   }
  return currval;
}

long long int GetMaximumCoins(const vector< vector< int > >& coins) {
  long long int answer = 0;
  // Top row.
  for(int i = 0; i < coins[0].size(); i++)
    answer = max(answer, GetDiagonalSum(coins, 0, i));
  // Left column.
  for(int i = 0; i < coins.size(); i++)
    answer = max(answer, GetDiagonalSum(coins, i, 0));
  return answer;
}
Test Data
info We recommend that you practice debugging solutions without looking at the test data.

Analysis — C. Combination Lock

We can see that if we decide a final value at which all wheels should be in the end, moves for each wheel to reach that value are independent of the moves performed on other wheels. Thus, we can calculate number of moves for each wheel separately. Consider a wheel i which is at value x currently. We want the wheel to finally reach the value y. There are 2 cases here:

  • Case 1: x ≤ y. Increasing the value of the wheel i would take y-x steps. Decreasing the value of wheel i would take N - y + x steps. Hence, the minimum number of moves in this case would be minimum of y-x and N - y + x.
  • Case 2: x > y. Decreasing the value of the wheel i would take x-y steps. Increasing the value of wheel i would take N + y - x steps. Hence, the minimum number of moves in this case would be minimum of x-y and N + y - x.

Test Set 1

We can solve this test set by trying all possible N values that all the wheels should have in the end. For each value, we calculate the total number of moves to get all of the wheels to this value using Case 1 and Case 2. The answer is the minimum possible moves performed over all such X. There are N possible values and for each value, we perform O(W) operations. Thus, the time complexity of the solution would be O(W × N).

Test Set 2

A major observation is that we could always get the minimum possible moves by finally bringing all the wheels to one of the initial values of the given wheels. We can prove this by considering a value Val which is not among the initial values of wheels and then showing that we can get a same or better answer by moving all the wheels to one of the initial values. Consider the initial values of the wheels in the sorted order. Let the index of the wheel with smallest initial value greater than Val be j, if no such value exists, then we can consider j = 1 as it is first wheel next to value Val in cyclic order. Let the index of wheel with largest initial value smaller than Val be i, if no such value exists, then we can consider i = W as it is the first wheel before value Val in cyclic order. Now to reach the value Val, each value will either reach Xi or Xj. Now say there are y wheels at value Xi currently which leaves us with W - y wheels at value Xj. The number of moves for all wheels to reach value Val would be y × (Val - Xi) + (W - y) × (Xj - Val). We can get the same or better result than this. There are 2 possibilities:

  • y ≤ W - y. If we choose to bring all the wheels to value Xj, we will have number of moves as y × (Val - Xi) + y × (Xj - Val), which is never large than the number of moves required for all wheels to reach value Val. Hence, we have a better answer if we bring all the wheels to value Xj.
  • y ≥ W - y. If we choose to bring all the wheels to value Xi, we will have number of moves as (W - y) × (Val - Xi) + (W - y) × (Xj - Val), which is never large than the number of moves required for all wheels to reach value Val. Hence, we have a better answer if we bring all the wheels to value Xi.

Now instead of trying all possible values from 1 to N, we would try the initial values of the wheels and calculate moves required for all wheels to reach that value. For each value, we take O(W) time to calculate the moves required for all wheels to reach that value. There are W values. Hence the complexity is O(W2).

Test Set 3

We have already proved that we only need to consider one of the initial values of the wheels. We need to calculate the number of moves required for all wheels to reach a particular value efficiently. We can do the following. Sort the initial values of the wheels. Maintain a prefix sum array Pre. Pre[i] denotes the sum of initial values of wheels from 1 to i. We define a method GetSum(i,j) which gives the sum of values between indexes i and j. This can be calulated in O(1) using Pre array.

Suppose that currently we are calulating the number of moves required for all wheels to reach Xi. Consider any wheel j from index 1 to i. Minimum number of moves required for wheel j to reach value Xi would be minimum of Xi - Xj and N - Xi + Xj. Consider 2 indexes k and l such that 1 ≤ k < l ≤ i. We can prove that it is not possible to have Xi - Xk < N - Xi + Xk and N - Xi + Xl < Xi - Xl simultaneously. This is because if we add the two inequalities, we get N - Xk + Xl < N + Xk - Xl which implies Xl < Xk. But it is not possible to have such condition because we know that XkXl. Thus, we can say that there exists an index p such that 1 ≤ p ≤ i and for each wheel q such that p ≤ q ≤ i will have minimum number of moves as Xi - Xq and for each wheel r such that 1 ≤ r ≤ p-1 will have minimum number of moves as N - Xi + Xr. We can find this index p using binary search on wheels 1 to i. Now we need to find sum of Xi - Xq for each q. This can be calculated in O(1) by (i - p + 1) × Xi - GetSum(p,i). Now we need to find sum of N - Xi + Xr for each r. This can be calculated in O(1) by (p-1) × (N - Xi) + GetSum(1,p-1). We have calculated number of moves required for wheels 1 to i to reach value Xi.

Similarly, we can say that there exists an index b such that i ≤ b ≤ W and for each wheel c such that i ≤ c ≤ b will have the minimum number of moves as Xc - Xi and for each wheel d such that b+1 ≤ d ≤ W will have the minimum number of moves as N - Xd + Xi. We can find this index b by using binary search on wheels 1 to W. Now we need to find sum of Xc - Xi for each c. This can be calculated in O(1) by GetSum(i+1,c) - (c-i) × Xi. Now we need to find sum of N - Xd + Xi for each d. This can be calculated in O(1) by (W - b) × (N + Xi) - GetSum(b+1,W).

We have calculated the number of moves required for all wheels to reach a particular value in O(log W). Now we need to take the minimum over all such values. Thus we can calculate moves for all the initial values of all wheels in O(W × log W) time complexity. Note that instead of using binary search to find indexes p and b, we can use two pointers approach to find them. We can prove that indexes p and b will keep on increasing as we increment i. The overall complexity of the solution remains same due to the sorting part.

Test Data
info We recommend that you practice debugging solutions without looking at the test data.

Analysis — D. Merge Cards

Test Set 1

In the i-th round, Panko will have N - i choices. In total, there are (N - 1)! possibilities. Using an exhaustive approach, the expected value can be computed by definition.

Test Set 2

After each round, the number on each card equals to the sum of a subarray of A. In the last round, there are N - 1 cases:

  • A1, A2 + A3 + ... + AN
  • A1 + A2, A3 + A4 + ... + AN
  • A1 + A2 + ... + Ai, Ai + 1 + Ai + 2 + ... + AN
  • A1 + A2 + ... + AN - 1, AN

The last round contributes a fixed number, A1 + A2 + ... + AN, to the answer. But in each case, the part contributed by the previous rounds is actually the sum of the answers of two variants of the original problem:

  • Replace A by A1, A2, ..., Ai
  • Replace A by Ai + 1, A2, ..., AN

This part is then a weighted average of those N - 1 sums. However, each case is equally likely to occur. To reach a specific case in the last round, Panko has to avoid exactly one choice in each of the previous rounds. Thus arithmetic mean can be used here.

There are O(N2) different subproblems. The answer of each of subproblem can be computed in O(N) by dynamic programming . The overall time complexity is then O(N3).

Test Set 3

The above solution can be optimized to achieve O(N2) time complexity by maintaining the prefix sums and suffix sums of the answers to the subproblems. But there is a faster approach that the O(N2) part is in precomputation instead of having O(N2) per test.

Let solveN(A1, A2, ..., AN) be a function that takes the N numbers written on the cards as parameters and returns the expected total score. It can be expressed as the average of N - 1 numbers. Each corresponds to a different choice in the first round. In particular, they are:

  • A1 + A2 + solveN - 1(A1 + A2, A3, ..., Ai, Ai + 1, ..., AN - 1, AN)
  • A2 + A3 + solveN - 1(A1, A2 + A3, ..., Ai, Ai + 1, ..., AN - 1, AN)
  • Ai + Ai + 1 + solveN - 1(A1, A2, A3, ..., Ai + Ai + 1, ..., AN - 1, AN)
  • AN - 1 + AN + solveN - 1(A1, A2, A3, ..., Ai, Ai + 1, ..., AN - 1 + AN)

By using mathematical induction with solve2(A1, A2) = A1 + A2 as the base case, it can be shown that solveN(A1, A2, ..., AN) is a linear combination of A1, A2, ..., AN, which means solveN(A1, A2, ..., AN) = kN, 1 × A1 + kN, 2 × A2 + ... + kN, N × AN where ki, j are constants. If all ki, j are precomputed, the answer for each test can be computed in time complexity O(N).

Starting from k2, 1 = k2, 2 = 1, ki, j can be computed in increasing order of i. The transition formulas can be obtained by transforming the formula of solveN(A1, A2, ..., AN). For example, the transition formula of kN, 1 can be obtained by replacing solveN - 1(...) and solveN(...) by the expressions with ki, j, then comparing the coefficients of the A1 term.

The j-th card will become either (part of) the (j - 1)-th card or (part of) the j-th card after a round. Correspondingly, only the coefficients of the ki - 1, j - 1 term, the ki - 1, j term and the constant term can be non-zero in the transition formula of ki, j. By grouping the like terms, the number of terms in each transition formula is reduced to at most 3. Then the overall time complexity becomes O(N2).

The error analysis is straightforward since Ai cannot be negative. It should not be a problem in most of the implementations.

Test Data
info We recommend that you practice debugging solutions without looking at the test data.

Statistics — A. Kick_Start

Statistics — B. Maximum Coins

Statistics — C. Combination Lock

Statistics — D. Merge Cards