2789 words
14 minutes
MCS April 25 Solutions & Explanation
2025-04-27
No Tags

The second iteration of Monthly Coding Series took place on April 25, 2025. The event was a great success, with many participants showcasing their skills in competitive programming. Below are the solutions and explanations for the problems presented during the contest.


Junior Category

Senior Category


Junior Category#

1. Queen Attack#

Problem Statement#

Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other.

In the game of chess, a queen can attack pieces which are on the same row, column, or diagonal.

A chessboard can be represented by an 8 by 8 array.

So if you are told the white queen is at c5 (zero-indexed at column 2, row 3) and the black queen at f2 (zero-indexed at column 5, row 6), then you know that the set-up is like so:

You are also able to answer whether the queens can attack each other. In this case, that answer would be yes, they can, because both pieces share a diagonal.

Explanation#

To determine if two queens can attack each other, we need to check the following conditions:

  1. If they are on the same row (i.e., their x-coordinates are equal).
  2. If they are on the same column (i.e., their y-coordinates are equal).
  3. If they are on the same diagonal (i.e., the absolute difference between their x-coordinates is equal to the absolute difference between their y-coordinates).
bool can_attack (int q1_x, int q1_y, int q2_x, int q2_y) {
    // Check if queens are on the same row or column
    if (q1_x == q2_x || q1_y == q2_y) {
        return true;
    }
    // Check if queens are on the same diagonal
    if (abs(q1_x - q2_x) == abs(q1_y - q2_y)) {
        return true;
    }
    return false;    
}

2. Eliud’s Eggs#

Problem Statement#

Introduction#

Your friend Eliud inherited a farm from her grandma Tigist. Her granny was an inventor and had a tendency to build things in an overly complicated manner. The chicken coop has a digital display showing an encoded number representing the positions of all eggs that could be picked up.

Eliud is asking you to write a program that shows the actual number of eggs in the coop.

The position information encoding is calculated as follows:

  1. Scan the potential egg-laying spots and mark down a 1 for an existing egg or a 0 for an empty spot.
  2. Convert the number from binary to decimal.
  3. Show the result on the display.
Example 1#

Seven individual nest boxes arranged in a row whose first, third, fourth and seventh nests each have a single egg.

 _ _ _ _ _ _ _
|E| |E|E| | |E|

Resulting Binary

1011001

 _ _ _ _ _ _ _
|1|0|1|1|0|0|1|

Decimal number on the display

89

Actual eggs in the coop

4

Example 2#

Seven individual nest boxes arranged in a row where only the fourth nest has an egg.

 _ _ _ _ _ _ _
| | | |E| | | |

Resulting Binary

0001000

 _ _ _ _ _ _ _
|0|0|0|1|0|0|0|

Decimal number on the display

8

Actual eggs in the coop

1

Instructions#

Your task is to count the number of 1 bits in the binary representation of a number.

Restrictions#

Keep your hands off that bit-count functionality provided by your standard library! Solve this one yourself using other basic tools instead.

Solution#

To count the number of 1 bits in the binary representation of a number, we can use a simple loop to check each bit of the number. We can do this by repeatedly checking the least significant bit (LSB) and then right-shifting the number until it becomes zero.

Division approach

int count_eggs (int display) {
    int count = 0;
    while (display > 0) {
        // Check if the remainder is 1
        if (display % 2) {
            count++;
        }
        // Remove the least significant bit
        display /= 2;
    }
    return count; 
}

Bitwise approach

int count_eggs (int display) {
    int count = 0;
    while (display > 0) {
        // Check if the least significant bit is 1
        if (display & 1) {
            count++;
        }
        // Right shift the number to check the next bit
        display >>= 1;
    }
    return count; 
}

3. Ugly Number#

Problem statement#

A number is ugly number is a positive integer whose prime factors are limited to 2, 3, and 5.

Given an integer n, return true if n is an ugly number.

Example 1#

Input: n = 6

Output: true

Explanation: 6 = 2 × 3

Solution#

To determine if a number is an ugly number, we can repeatedly divide the number by 2, 3, and 5 until it becomes 1 or cannot be divided further. If the final result is 1, then the number is an ugly number.

#include <stdio.h>

int main(){
    int num;
    scanf("%d", &num);

    while(num % 2 == 0) {
        num /= 2;
    }
    while(num % 3 == 0) {
        num /= 3;
    }
    while(num % 5 == 0) {
        num /= 5;
    }

    if(num == 1) {
        printf("true\n");
    } else {
        printf("false\n");
    }
}

4. Sum of digits in single digit#

Problem statement#

WAP to find sum of digits of a number until sum becomes single digit.

Input : 1234

Output : 1

Explanation:

The sum of 1 + 2 + 3 + 4 = 10 (two digit)

Hence ans will be 1 + 0 = 1

Solution#

int sumofdigit (int n) 
{
    int sum;
    
    do {
        sum = 0;
        while (n > 0) {
            sum += n % 10; // Add the last digit to sum
            n /= 10; // Remove the last digit
        }
        n = sum; // Update n to the sum of digits
    } while (n > 9); // Repeat until sum is a single digit

    return sum;
}

5. Space Age#

Problem statement#

Introduction#

The year is 2525 and you’ve just embarked on a journey to visit all planets in the Solar System (Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus and Neptune). The first stop is Mercury, where customs require you to fill out a form (bureaucracy is apparently not Earth-specific). As you hand over the form to the customs officer, they scrutinize it and frown. “Do you really expect me to believe you’re just 50 years old? You must be closer to 200 years old!”

Amused, you wait for the customs officer to start laughing, but they appear to be dead serious. You realize that you’ve entered your age in Earth years, but the officer expected it in Mercury years! As Mercury’s orbital period around the sun is significantly shorter than Earth, you’re actually a lot older in Mercury years. After some quick calculations, you’re able to provide your age in Mercury Years. The customs officer smiles, satisfied, and waves you through. You make a mental note to pre-calculate your planet-specific age before future customs checks, to avoid such mix-ups.

Instructions#

Given an age in seconds, calculate how old someone would be on a planet in our Solar System.

One Earth year equals 365.25 Earth days, or 31,557,600 seconds. If you were told someone was 1,000,000,000 seconds old, their age would be 31.69 Earth-years.

For the other planets, you have to account for their orbital period in Earth Years:

PlanetOrbital period in Earth Years
Mercury0.2408467
Venus0.61519726
Earth1.0
Mars1.8808158
Jupiter11.862615
Saturn29.447498
Uranus84.016846
Neptune164.79132

Solution#

To calculate the age on a specific planet, we first convert the given seconds into Earth years. Then, we divide that by the planet’s orbital period in Earth years to get the age on that planet.

double space_age (char* planet, int seconds) {
    double earth_years = seconds / 31557600.0; // Convert seconds to Earth years
    
    if (strcmp(planet, "Mercury") == 0) {
        return earth_years / 0.2408467; // Mercury's orbital period
    } else if (strcmp(planet, "Venus") == 0) {
        return earth_years / 0.61519726; // Venus's orbital period
    } else if (strcmp(planet, "Earth") == 0) {
        return earth_years; // Earth
    } else if (strcmp(planet, "Mars") == 0) {
        return earth_years / 1.8808158; // Mars's orbital period
    } else if (strcmp(planet, "Jupiter") == 0) {
        return earth_years / 11.862615; // Jupiter's orbital period
    } else if (strcmp(planet, "Saturn") == 0) {
        return earth_years / 29.447498; // Saturn's orbital period
    } else if (strcmp(planet, "Uranus") == 0) {
        return earth_years / 84.016846; // Uranus's orbital period
    } else if (strcmp(planet, "Neptune") == 0) {
        return earth_years / 164.79132; // Neptune's orbital period
    }

    return -1; // Invalid planet name
}

Senior Category#

1. Best Time to Buy and Sell Stock#

Problem statement#

You are given an integer array prices where prices[i] is the price of a given stock on the ith day.

On each day, you may decide to buy and/or sell the stock. You can only hold at most one share of the stock at any time. However, you can buy it then immediately sell it on the same day.

Find and return the maximum profit you can achieve.

Input Format:

  • An integer value n representing size of the array
  • Next line contains n space separated integer values of the array.
Example 1#

Input: prices = [7,1,5,3,6,4]

Output: 7

Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. Total profit is 4 + 3 = 7.

Example 2#

Input: prices = [1,2,3,4,5]

Output: 4

Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. Total profit is 4.

Example 3#

Input: prices = [7,6,4,3,1]

Output: 0

Explanation: There is no way to make a positive profit, so we never buy the stock to achieve the maximum profit of 0.

Constraints#

1 <= prices.length <= 3 * 104

0 <= prices[i] <= 104

Solution#

Video Explanation

int max_profit (int* stocks, int days) {
    int profit = 0;
    for (int i = 1; i < days; i++) {
        if (stocks[i] > stocks[i-1]) {
            profit += stocks[i] - stocks[i-1];
        }
    }
    return profit;
}

2. Longest Substring Without Repeating Characters#

Problem statement#

Given a string s, find the length of the longest substring without repeating characters.

Input Format:-

Only one line that contains the string.

Output Format:-

Print te length of longest substring without repeating characters.

Constraint:-

  • 0 <= s.length <= 5 * 104
  • s consists of English letters, digits, symbols and spaces.

Solution#

To find the length of the longest substring without repeating characters, we can use a sliding window approach with a map to keep track of the last known index of each character.

We will maintain two pointers, start and end, to represent the current substring. As we iterate through the string, we will update the start pointer whenever we encounter a repeating character.

We will also keep track of the maximum length of the substring found so far.

#define max(x, y) x > y ? x : y

int last_known_index[256];

int longest_substring (char* input) {
    // reset the last known index map
    for (int i = 0; i < 256; i++) {
        last_known_index[i] = -1;
    }

    int start = 0;
    int end = 0;
    int longest = 0;

    while (input[end] != '\0') {
        char c = input[end];

        if (last_known_index[c] >= start) {
            longest = max(longest, end - start);
            start = last_known_index[c] + 1;
        }

        last_known_index[c] = end;
        end++;
    }

    return max(longest, end - start);
}

3. Sum of digits in single digit#

Same as Junior Category Question 4

4. Longest Palindrome#

Problem statement#

Given a string, your task is to determine the longest palindromic substring of the string. For example, the longest palindrome in aybabtu is bab.

Input

The only input line contains a string of length n. Each character is one of a-z.

Output

Print the longest palindrome in the string. If there are several solutions, you may print any of them.

Constraints

1n1061 ≤ n ≤ 10^6

Solution#

Video Explanation

#include <string.h>

char* longest_palindrome (char* input) {
    int n = strlen(input);
    if (n == 0) return "";

    int start = 0, max_length = 1;

    for (int i = 0; i < n; i++) {
        // Check for odd length palindromes
        int left = i, right = i;
        while (left >= 0 && right < n && input[left] == input[right]) {
            if (right - left + 1 > max_length) {
                start = left;
                max_length = right - left + 1;
            }
            left--;
            right++;
        }

        // Check for even length palindromes
        left = i, right = i + 1;
        while (left >= 0 && right < n && input[left] == input[right]) {
            if (right - left + 1 > max_length) {
                start = left;
                max_length = right - left + 1;
            }
            left--;
            right++;
        }
    }

    // Extract the longest palindrome substring
    char* result = (char*)calloc((max_length + 1), sizeof(char));
    strncpy(result, &input[start], max_length);
    return result;
}

5. String Matching#

Problem statement#

Given a string and a pattern, your task is to count the number of positions where the pattern occurs in the string.

Input

The first input line has a string of length n, and the second input line has a pattern of length m. Both of them consist of characters a-z.

Output

Print one integer: the number of occurrences.

Constraints

1n,m1061 ≤ n,m ≤ 10^6

Solution#

Naive String Matching Algorithm

#include<string.h>

int substring_count (char* input, char* pattern) {
    // Naive string matching
    int n_input = strlen(input);
    int n_pattern = strlen(pattern);
    int count = 0;

    for (int i = 0; i < n_input - n_pattern + 1; i++) {
        if(strncmp(input + i, pattern, n_pattern) == 0){
            count++;
        }
    }
    return count;
}

Improvements -

  • KMP Algorithm
  • Rabin-Karp Algorithm
  • Z Algorithm

6. Knapsack#

Problem statement#

Introduction#

Lhakpa is a Sherpa mountain guide and porter. After months of careful planning, the expedition Lhakpa works for is about to leave. She will be paid the value she carried to the base camp.

In front of her are many items, each with a value and weight. Lhakpa would gladly take all of the items, but her knapsack can only hold so much weight.

Instructions#

Your task is to determine which items to take so that the total value of her selection is maximized, taking into account the knapsack’s carrying capacity.

Items will be represented as a list of items. Each item will have a weight and value. All values given will be strictly positive. Lhakpa can take only one of each item.

For example:

Items: [
  { "weight": 5, "value": 10 },
  { "weight": 4, "value": 40 },
  { "weight": 6, "value": 30 },
  { "weight": 4, "value": 50 }
]

Knapsack Maximum Weight: 10 For the above, the first item has weight 5 and value 10, the second item has weight 4 and value 40, and so on. In this example, Lhakpa should take the second and fourth item to maximize her value, which, in this case, is 90. She cannot get more than 90 as her knapsack has a weight limit of 10.

Solution#

Video Explanation

#define max(x, y) x > y ? x : y

#define WEIGHT 0
#define VALUE 1

// Function to allocate a 2D matrix
int** alloc_matrix(int rows, int cols) {
    int** matrix = (int**) calloc(rows, sizeof(int*));
    for (int row = 0; row < rows; row ++){
        matrix[row] = (int*) calloc(cols, sizeof(int)); 
    }
    return matrix;
}

// Function to free a 2D matrix
void free_matrix(int** matrix, int rows){
    for (int row = 0; row < rows; row ++){
        free(matrix[row]); 
    }
    free(matrix);
}


int kanpsack (int n_item, int n_property, int** items, int capacity) {
    // Initialize a matrix of 
    // rows: items + 1 
    // columns: knapsack capacity + 1 
    int** matrix = alloc_matrix(n_item + 1, capacity + 1);

    for (int item = 0; item < n_item; item++) {
        for(int weight = 1; weight <= capacity; weight++) {
            
            int item_weight = items[item][WEIGHT];
            int item_value = items[item][VALUE];
            

            // Maximum value while exluding current item
            int exclude_value = max(matrix[item+1][weight-1], matrix[item][weight]);

            // current item cannot fit in current weight
            if (items[item][WEIGHT] > weight) {
                matrix[item + 1][weight] = exclude_value;
            } 
            // current item can fit in current weight
            else {
                // Value when including current item
                int include_value = item_value + matrix[item][weight-item_weight];
                
                // Maximum value for current weight
                matrix[item + 1][weight] = max(include_value, exclude_value);
            }
        }
    }

    // Max value is the last cell
    int max_value = matrix[n_item][capacity];
    // Free the allocated matrix
    free_matrix(matrix, n_item + 1);
    // Return the maximum value
    return max_value;
}

7. Counting Ways to Form a Sum with Coins#

Problem statement#

Consider a money system consisting of n coins. Each coin has a positive integer value. Your task is to calculate the number of distinct ways you can produce a money sum x using the available coins.

For example, if the coins are {2,3,5} and the desired sum is 9, there are 8 ways:

  • 2+2+5
  • 2+5+2
  • 5+2+2
  • 3+3+3
  • 2+2+2+3
  • 2+2+3+2
  • 2+3+2+2
  • 3+2+2+2

Input

The first input line has two integers n and x: the number of coins and the desired sum of money.

The second line has n distinct integers c1c_1,c2c_2,…,cnc_n: the value of each coin.

Output

Print one integer: the number of ways modulo 109+710^9+7.

Constraints

1n1001 ≤ n ≤ 100

1x1061 ≤ x ≤ 10^6

1ci1061 ≤ c_i ≤ 10^6

Solution#

Video Explanation

const int MOD = 1e9 + 7;

int ways (int n_coin, int amount, int* coins) {
    int* dp = (int *) calloc(amount+1, sizeof(int));

    dp[0] = 1;

    for(int current_amount = 1; current_amount <= amount; current_amount++){
        for(int coin = 0; coin < n_coin; coin++) {
            if(current_amount - coins[coin] >= 0) {
                dp[current_amount] = (dp[current_amount] + dp[current_amount - coins[coin]]) % MOD;
            }
        }
    }

    int ans = dp[amount];
    free(dp);
    return ans;
}