Open In App

CSES Solutions – Apartments

Last Updated : 01 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

There are N applicants and M free apartments. Your task is to distribute the apartments so that as many applicants as possible will get an apartment. Each applicant has a desired apartment size given in array A[] of size N and each apartment has a size given in array B[] of size M. An applicant will accept any apartment whose size is close enough to the desired size. The applicant will accept the apartment if the absolute difference between the size of the apartment and his desired apartment size <= K.

Examples:

Input: N = 4, M = 3, K = 5, A[] = {60, 45, 80, 60}, B[] = {30, 60, 75}
Output: 2
Explanation:

  • The first applicant can take any apartment which has size in range 55 to 65. So, he will take the apartment with size 60.
  • The second applicant can take any apartment which has size in range 40 to 50. So, he won’t be able to take any apartment.
  • The third applicant can take any apartment which has size in range 75 to 85. So, he will take the apartment with size 75.
  • The fourth applicant can take any apartment which has size in range 55 to 65. So, he won’t be able to take any apartment as the apartment with size 60 is already taken by second applicant.

Input: N = 3, M = 3, K = 10, A[] = {30, 40, 50}, B[] = {40, 50, 60}
Output: 3
Explanation:

  • The first applicant can take any apartment which has size in range 20 to 40. So, he will take the apartment with size 40.
  • The second applicant can take any apartment which has size in range 30 to 50. So, he will take the apartment with size 50.
  • The third applicant can take any apartment which has size in range 40 to 60. So, he will take the apartment with size 60.

Approach: To solve the problem, follow the below idea:

The problem can be solved using a Greedy approach. We can sort both the arrays A[] and B[] in ascending order and maintain two pointers, say ptrA and ptrB to mark the current index. Now, we can run a loop till we reach the end of one of the array. According to the values of A[] and B, we can have 3 cases:

  • abs(A[ptrA] – B[ptrB]) <= K: This means that the applicant at index ptrA can accept the apartment at index ptrB. So, we will increment the answer by 1 and move to the next applicant and apartment.
  • A[ptrA] < B[ptrB]: This means that the apartment at index ptrB has much greater size that the applicant’s desired size. Since, we have already allotted all the apartments with smaller size (as the arrays are sorted in ascending order) the only choice is to move to the next applicant whose desired size will be greater.
  • A[ptrA] > B[ptrB]: This means that the apartment at index ptrB has much smaller size that the applicant’s desired size. Since, all the applicants who desired a smaller apartment have already got their apartments (as the arrays are sorted in ascending order) the only choice is to move to the next apartment whose size will be greater.

Step-by-step algorithm:

  • Sort both the arrays A[] and B[] in ascending order.
  • Maintain a pointer for each array to keep track of the current value, say ptrA for array A[] and ptrB for array B[].
  • Check if difference between the current values is less than equal to K, then the applicant at index ptrA will purchase the apartment at index ptrB and we will increment both the pointers.
  • Otherwise, if the difference is greater than K, we will try to increase whichever is smaller among A[ptrA] and B[ptrB].
  • We will continue this till we reach the end of A[] or B[].

Below is the implementation of the algorithm:

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

// function to allot apartments to applicants
int solve(vector<int>& A, vector<int>& B, int N, int M,
        int K)
{
    // Sort both the arrays in ascending order
    sort(A.begin(), A.end());
    sort(B.begin(), B.end());

    // Maintain two pointers to store the current value in
    // both the arrays
    int ptrA = 0, ptrB = 0, ans = 0;
    while (ptrA < N && ptrB < M) {
        // Check if the applicant at index ptrA can purchase
        // the apartment at index ptrB
        if (abs(A[ptrA] - B[ptrB]) <= K) {
            // Increase the number of purchase
            ans += 1;
            ptrA += 1;
            ptrB += 1;
        }
        // If the current applicant's demand is too small,
        // we will move to the next applicant
        else if (A[ptrA] < B[ptrB]) {
            ptrA += 1;
        }
        // If the current apartment's size is too small, we
        // will move to the next apartment
        else {
            ptrB += 1;
        }
    }
    return ans;
}

int main()
{
    // Sample Input
    int N = 4, M = 3, K = 5;
    vector<int> A = { 60, 45, 80, 60 };
    vector<int> B = { 30, 60, 75 };

    cout << solve(A, B, N, M, K);

    return 0;
}
Java
import java.util.Arrays;

public class ApartmentAllotment {

    // Function to allot apartments to applicants
    static int solve(int[] A, int[] B, int N, int M, int K)
    {
        // Sort both the arrays in ascending order
        Arrays.sort(A);
        Arrays.sort(B);

        // Maintain two pointers to store the current value
        // in both the arrays
        int ptrA = 0, ptrB = 0, ans = 0;
        while (ptrA < N && ptrB < M) {
            // Check if the applicant at index ptrA can
            // purchase the apartment at index ptrB
            if (Math.abs(A[ptrA] - B[ptrB]) <= K) {
                // Increase the number of purchases
                ans += 1;
                ptrA += 1;
                ptrB += 1;
            }
            // If the current applicant's demand is too
            // small, move to the next applicant
            else if (A[ptrA] < B[ptrB]) {
                ptrA += 1;
            }
            // If the current apartment's size is too small,
            // move to the next apartment
            else {
                ptrB += 1;
            }
        }
        return ans;
    }

    public static void main(String[] args)
    {
        // Sample Input
        int N = 4, M = 3, K = 5;
        int[] A = { 60, 45, 80, 60 };
        int[] B = { 30, 60, 75 };

        System.out.println(solve(A, B, N, M, K));
    }
}

// This code is contributed by akshitaguprzj3
Python
def solve(A, B, N, M, K):
    # Sort both the arrays in ascending order
    A.sort()
    B.sort()

    # Maintain two pointers to store the current value
    # in both the arrays
    ptrA, ptrB, ans = 0, 0, 0
    while ptrA < N and ptrB < M:
        # Check if the applicant at index ptrA can
        # purchase the apartment at index ptrB
        if abs(A[ptrA] - B[ptrB]) <= K:
            # Increase the number of purchases
            ans += 1
            ptrA += 1
            ptrB += 1
        # If the current applicant's demand is too
        # small, move to the next applicant
        elif A[ptrA] < B[ptrB]:
            ptrA += 1
        # If the current apartment's size is too small,
        # move to the next apartment
        else:
            ptrB += 1
    return ans


# Sample Input
N, M, K = 4, 3, 5
A = [60, 45, 80, 60]
B = [30, 60, 75]

print(solve(A, B, N, M, K))
C#
using System;
using System.Collections.Generic;

class GFG
{
    // function to allot apartments to applicants
    static int Solve(List<int> A, List<int> B, int N, int M, int K)
    {
        // Sort both the arrays in ascending order
        A.Sort();
        B.Sort();

        // Maintain two pointers to store the current value in
        // both the arrays
        int ptrA = 0, ptrB = 0, ans = 0;
        while (ptrA < N && ptrB < M)
        {
            // Check if the applicant at index ptrA can purchase
            // the apartment at index ptrB
            if (Math.Abs(A[ptrA] - B[ptrB]) <= K)
            {
                // Increase the number of purchase
                ans += 1;
                ptrA += 1;
                ptrB += 1;
            }
            // If the current applicant's demand is too small,
            // we will move to the next applicant
            else if (A[ptrA] < B[ptrB])
            {
                ptrA += 1;
            }
            // If the current apartment's size is too small, we
            // will move to the next apartment
            else
            {
                ptrB += 1;
            }
        }
        return ans;
    }

    static void Main()
    {
        // Sample Input
        int N = 4, M = 3, K = 5;
        List<int> A = new List<int> { 60, 45, 80, 60 };
        List<int> B = new List<int> { 30, 60, 75 };

        Console.WriteLine(Solve(A, B, N, M, K));
    }
}
JavaScript
// Function to allot apartments to applicants
function solve(A, B, N, M, K) {
    // Sort both the arrays in ascending order
    A.sort((a, b) => a - b);
    B.sort((a, b) => a - b);

    // Maintain two pointers to store the current value in both arrays
    let ptrA = 0;
    let ptrB = 0;
    let ans = 0;

    while (ptrA < N && ptrB < M) {
        // Check if the applicant at index ptrA can purchase
        // the apartment at index ptrB
        if (Math.abs(A[ptrA] - B[ptrB]) <= K) {
            // Increase the number of purchases
            ans += 1;
            ptrA += 1;
            ptrB += 1;
        }
        // If the current applicant's demand is too small,
        // move to the next applicant
        else if (A[ptrA] < B[ptrB]) {
            ptrA += 1;
        }
        // If the current apartment's size is too small,
        // move to the next apartment
        else {
            ptrB += 1;
        }
    }

    return ans;
}

// Sample Input
const N = 4;
const M = 3;
const K = 5;
const A = [60, 45, 80, 60];
const B = [30, 60, 75];

console.log(solve(A, B, N, M, K));

Output
2

Time Complexity: O(NlogN + MlogM), where N is the number of applicants and M is the number of apartments.
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads