We will discuss the solution to Pairing Cards from AIO 2025.
Since S = 0 and Ai ≥ 1 for all i, it is impossible for any pair to add to S in this subtask. All pairs must have a difference of D.
A card with a value of Ai could be paired with a value of either Ai - D or Ai + D and it's not clear which one we should choose. But if we instead look at the card with the smallest value (A1) there is only one option to pair it with: A1 + D (we can ignore A1 - D because it has a smaller value which contradicts the fact that A1 has the smallest value). If there is no card with value A1 + D then we can output NO and stop our program. Otherwise, we pair A1 with A1 + D, remove these two cards, and repeat this process using the new smallest card.
Below is my code in Python and C++ for this subtask. I suggest trying to code the solution yourself and only look at our code after you finish or if you get stuck. Make sure your code works when D = 0 because this case can be tricky!
import sys
# N is the number of cards.
N = 0
# D and S are the allowed difference and sum of paired cards.
D = 0
S = 0
# A contains the values on the cards. Note that the list starts from 0, and so
# the values are A[0] to A[N-1].
A = []
# Read the values of N, D, S, and the values on the cards.
N, D, S = map(int, input().strip().split())
A = list(map(int, input().strip().split()))
while len(A) > 0:
# pair A[0] with A[0]+D
value = A[0]
A.remove(value)
if value+D not in A:
print("NO")
sys.exit(0) # this ends the program
else:
# A[0]+D from the list
A.remove(value+D)
print("YES")
#include <cstdio>
#include <vector> // for std::vector
#include <algorithm> // for std::find
/* N is the number of cards. */
int N;
/* D and S are the allowed difference and sum of paired cards. */
int D;
int S;
std::vector<int> A;
int main(void) {
/* Read the values of N, D, S, and the values on the cards. */
scanf("%d%d%d", &N, &D, &S);
for (int i = 0; i < N; i++) {
int a;
scanf("%d", &a);
A.push_back(a);
}
while (!A.empty()) {
int value = A[0];
A.erase(A.begin());
auto it = std::find(A.begin(), A.end(), value+D);
if (it == A.end()) {
printf("NO\n");
return 0;
} else {
A.erase(it);
}
}
printf("YES\n");
}
In this subtask we can either pair equal values or values that add to S.
Assume for now that all values are distinct and so our only option is to pair values that add to S. In this case we don't need to make any pairing decisions: for each value Ai our only option is to pair it with a card of value S - Ai. This allows us to use code similar to subtask 1: we continuously try pairing cards until either we can't (so we print NO) or all the cards are paired (so we print YES).
When the values are not all distinct then we need to make a choice. For example, if there are two cards with value Ai = x we need to choose whether to pair them together or to pair them both with cards of value S - x.
The first option (pair them together) is always optimal — try to prove it yourself and then read my proof.
We will use a type of proof called an exchange argument.
In this proof style, we start with a solution that does not meet the criteria of our observation and we prove that we can
Assume we did not pair the two cards together.
Then, we paired the two cards of value x with two cards of value S - x.
However, we could swap the pairs around so that the two x's are paired together and the two S - x's are also paired together.
Proof
change
it so that it does meet our criteria.
Our solution is: first pair cards of equal value until no such pairs remain. Then, all remaining cards have distinct values and we can use the method described above.
In these subtasks each card has three options for what it could be paired with:
Depending on the time complexity of your solution it will pass either subtasks 1-3 or the full problem.
Two examples of this algorithm are shown below.