Open In App

CSES Solutions – Coin Piles

You are given Q queries. In each query, you have two coin piles containing A and B coins. On each move, you can either remove one coin from the left pile and two coins from the right pile, or two coins from the left pile and one coin from the right pile. Your task is to efficiently find out if you can empty both the piles.

Examples:

Input: Q = 3, queries[][] = {{2, 1}, {2, 2}, {3, 3}}
Output:
YES
NO
YES
Explanation:

  • In the first query, you can remove 2 coins from the first pile and 1 coin from the second pile to empty both the piles.
  • In the second query, there is no possible way to empty both the piles.
  • In the third query, you can first remove 2 coins from the first pile and 1 coin from the second pile, then remove 1 coin from the first pile and remove 2 coins from the second pile.

Input: Q = 2, queries[][] = {{1, 1}, {2, 2}}
Output:
NO
NO
Explanation: In the first and second query, there is no possible way to empty both the piles.

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

For a query, we have 2 piles having A and B coins. Let's say we remove 1 coin from the first pile X number of times and remove 2 coins from the first pile Y number of times. So, if we want to empty the first pile, the following equation should be true:

1 * X + 2 * Y = A (Equation 1)

When we remove 1 coin from the first pile, we also remove 2 coins from the second pile. Similarly, when we remove 2 coins from the first pile, we also remove 1 coin from the second pile. So, if we want to empty the first pile, the following equation should be true:

2 * X + 1 * Y = B (Equation 2)

Simplifying the above equations, we get the value of X = (2 * B - A)/3 and the value of Y = (2 * A - B)/3. So, to check whether it is possible to empty both the piles, (2 * B - A) should be positive and divisible by 3 and (2 * A - B) should pe positive and divisible by 3.

Step-by-step algorithm:

Below is the implementation of the algorithm:

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

string solve(int A, int B)
{
    // X * 2 + Y * 4 = 2 * A
    // X * 2 + Y * 1 = B
    // 3 * Y = 2 * A - B
    // Y = (2 * A - B)/3

    // X + Y * 2 = A
    // 4 * X + 2 * Y = 2 * B
    // -3 * X = A - 2 * B
    // X = (2 * B - A) / 3

    if ((2 * A - B) % 3 || (2 * A - B) < 0
        || (2 * B - A) % 3 || (2 * B - A) < 0)
        return "NO\n";
    return "YES\n";
}

int main()
{
    int Q = 3;
    vector<vector<int>> queries = {{2, 1}, {2, 2}, {3, 3}};
    for(int i = 0; i < Q; i ++) {
        int A = queries[i][0], B = queries[i][1];
        cout << solve(A, B);
    }
}
import java.util.ArrayList;
import java.util.List;

public class Main {

    static String solve(int A, int B) {
        // X * 2 + Y * 4 = 2 * A
        // X * 2 + Y * 1 = B
        // 3 * Y = 2 * A - B
        // Y = (2 * A - B) / 3

        // X + Y * 2 = A
        // 4 * X + 2 * Y = 2 * B
        // -3 * X = A - 2 * B
        // X = (2 * B - A) / 3

        if ((2 * A - B) % 3 != 0 || (2 * A - B) < 0 ||
            (2 * B - A) % 3 != 0 || (2 * B - A) < 0) {
            return "NO\n";
        }
        return "YES\n";
    }

    public static void main(String[] args) {
        int Q = 3;
        List<List<Integer>> queries = new ArrayList<>();
        queries.add(List.of(2, 1));
        queries.add(List.of(2, 2));
        queries.add(List.of(3, 3));

        for (int i = 0; i < Q; i++) {
            int A = queries.get(i).get(0);
            int B = queries.get(i).get(1);
            System.out.print(solve(A, B));
        }
    }
}

// This code is contributed by shivamgupta0987654321
using System;
using System.Collections.Generic;

public class Program
{
    public static string Solve(int A, int B)
    {
        // X * 2 + Y * 4 = 2 * A
        // X * 2 + Y * 1 = B
        // 3 * Y = 2 * A - B
        // Y = (2 * A - B) / 3

        // X + Y * 2 = A
        // 4 * X + 2 * Y = 2 * B
        // -3 * X = A - 2 * B
        // X = (2 * B - A) / 3

        if ((2 * A - B) % 3 != 0 || (2 * A - B) < 0 ||
            (2 * B - A) % 3 != 0 || (2 * B - A) < 0)
            return "NO";
        return "YES";
    }

    public static void Main(string[] args)
    {
        int Q = 3;
        List<List<int>> queries = new List<List<int>>()
        {
            new List<int>() {2, 1},
            new List<int>() {2, 2},
            new List<int>() {3, 3}
        };
        
        for (int i = 0; i < Q; i++)
        {
            int A = queries[i][0], B = queries[i][1];
            Console.WriteLine(Solve(A, B));
        }
    }
}
function solve(A, B) {
    // X * 2 + Y * 4 = 2 * A
    // X * 2 + Y * 1 = B
    // 3 * Y = 2 * A - B
    // Y = (2 * A - B) / 3

    // X + Y * 2 = A
    // 4 * X + 2 * Y = 2 * B
    // -3 * X = A - 2 * B
    // X = (2 * B - A) / 3

    if ((2 * A - B) % 3 !== 0 || (2 * A - B) < 0 ||
        (2 * B - A) % 3 !== 0 || (2 * B - A) < 0) {
        return "NO\n";
    }
    return "YES\n";
}

const Q = 3;
const queries = [[2, 1], [2, 2], [3, 3]];

for (const query of queries) {
    const A = query[0];
    const B = query[1];
    console.log(solve(A, B));
}
def solve(A, B):
    # X * 2 + Y * 4 = 2 * A
    # X * 2 + Y * 1 = B
    # 3 * Y = 2 * A - B
    # Y = (2 * A - B) / 3

    # X + Y * 2 = A
    # 4 * X + 2 * Y = 2 * B
    # -3 * X = A - 2 * B
    # X = (2 * B - A) / 3

    if (2 * A - B) % 3 != 0 or (2 * A - B) < 0 \
            or (2 * B - A) % 3 != 0 or (2 * B - A) < 0:
        return "NO\n"
    return "YES\n"

if __name__ == "__main__":
    Q = 3
    queries = [[2, 1], [2, 2], [3, 3]]
    for query in queries:
        A, B = query[0], query[1]
        print(solve(A, B), end="")

Output
YES
NO
YES

Time Complexity: O(1)
Auxiliary Space: O(1)

Article Tags :