Basecamp
    Home
    Problems
    Contests
    Courses
    Rating
    Posts
    Discord
Two pointers technique
Sign in
medv
•Article•6 months ago

Two pointers technique

The Two Pointers technique is a strategy commonly used in computer science and programming for solving problems involving arrays or sequences. It involves using two pointers that traverse the array or sequence from different positions, often moving in opposite directions or at different speeds. This technique is particularly useful for solving problems related to searching, optimization, or manipulation of arrays efficiently.

Here's a breakdown of how the Two Pointers technique works:

  • Initialization: Initially, you set up two pointers, usually at different positions within the array or sequence.

  • Movement: You iteratively move the pointers based on certain conditions until they meet or reach a specific condition. The movement of pointers can be controlled based on the problem requirements. For example, one pointer might move faster than the other, or they might move in opposite directions.

  • Condition Checking: At each step of iteration, you check certain conditions based on the problem requirements. These conditions often determine whether to move the pointers, update some variables, or perform other operations.

  • Termination: The process continues until one or both pointers reach the end of the array or sequence, or until some other termination condition is met.

The Two Pointers technique is especially useful in problems that involve searching for pairs or subarrays that meet specific criteria, finding optimal solutions, or manipulating sequences efficiently without using nested loops. It often provides a more efficient solution compared to brute-force approaches, especially for problems with linear or logarithmic time complexity requirements.

Eolymp #2098. Invertor

Given n integers. Print them in reverse order.

Input. First given number n (0<n<100), then given n integers.

Output. Print the given n integers in reverse order.

Sample input
7
2 4 1 3 5 3 1
Sample output
1 3 5 3 1 4 2
Open problem
Solution

Store the numbers in a linear array. Then print them in reverse order.

Let’s consider a solution for reversing an array using the two-pointer technique.

Set two variables i and j (we'll call them pointers):

  • i at the beginning of the array (i=1);

  • j at the end of the array (j=n);

Next, start a while loop, in which:

  • the values of m[i] and m[j] are swapped;

  • then i is incremented by 1, and j is decremented by 1;

We continue the loop until the pointers i and j meet.

Note that the values of m[i] and m[j] can be swapped using an additional variable temp by performing three operations:

Algorithm implementation

Declare an array.

#define MAX 110
int m[MAX];

Read the input data.

scanf("%d",&n);
for(i = 1; i <= n; i++)
  scanf("%d",&m[i]);

Reverse the array using the two-pointer technique.

i = 1; j = n;
while(i < j)
{
  temp = m[i]; m[i] = m[j]; m[j] = temp;
  i++; j--;
}

Print the numbers.

for(i = 1; i <= n; i++)
  printf("%d ",m[i]);
printf("\n");
Eolymp #11387. Cards game

Huseyn and Yaroslav are playing a card game. There are n cards laid out in a row on the table, each with a different number written on it. The players take turns. Huseyn starts the game. On each turn, a player can take either the leftmost or the rightmost card. The player will always choose the card with the highest number. The game ends when there are no cards left on the table. Find the sum of the numbers on the cards collected by Huseyn and Yaroslav at the end of the game.

Input. The first line contains the number of cards n (1≤n≤10000) on the table. The second line contains n positive integers, each indicating the number on a card. All numbers are not greater than 109.

Output. Print the sum of the numbers on the cards collected by Huseyn and Yaroslav at the end of the game.

Sample input
7
4 7 5 1 12 8 2
Sample output
18 21
Open problem
Solution

Let the array m contain the numbers written on the cards. We initialize pointers i=0 at the beginning of the array and j=n−1 at the end of the array.

On each turn, a player takes the card with the maximum value max(m[i],m[j]), after which the card is removed from the table (perform the operation i++ if the card m[i] is chosen, and j−− if the card m[j] is chosen). For each player, we keep track of the sum of the selected cards in two variables. The process continues until all cards are removed from the table, that is, until the pointers i and j meet.

Example

The game will proceed as follows.

Algorithm implementation

Declare the arrays. The sum of the numbers on the cards collected by Huseyn and Yaroslav will be stored in res[0] and res[1], respectively.

int m[10001], res[2];

Read the input data.

scanf("%d", &n);
for (i = 0; i < n; i++)
  scanf("%d", &m[i]);

Set the pointers i=0 and j=n−1.

i = 0; j = n - 1;

The players take turns, making n moves in total. Huseyn takes turns for even k, and Yaroslav takes turns for odd k. Accordingly, Huseyn's sum will accumulate in res[0], and Yaroslav's sum will accumulate in res[1].

for (k = 0; k < n; k++)
{

On each turn, the player chooses the card with the maximum value max(m[i],m[j]).

  if (m[i] > m[j])
    res[k % 2] += m[i++];
  else
    res[k % 2] += m[j--]; ;
}

Print the answer.

printf("%d %d\n", res[0], res[1]);
Eolymp #11388. Cards game 2

Huseyn arranged n cards in a row with numbers a1​,a2​,a3​,...,an​. Then he collected them and rearranged them in a different order: a1​,a3​,a5​,...,a6​,a4​,a2​. This is the sequence he gave to Yaroslav. Your task is to help Yaroslav restore Hussein's original sequence.

For example, if Yaroslav received the sequence (2,4,9,4,7,6), then he should return the sequence (2,6,4,7,9,4) to Huseyn.

Input. The first line contains one integer n (1≤n≤10000), representing the number of cards. The second line contains n positive integers written on the cards. All numbers are no greater than 109.

Output. Print Huseyn's original sequence.

Sample input 1
6
2 4 9 4 7 6
Sample output 1
2 6 4 7 9 4
Sample input 2
7
5 7 34 1 89 4 2
Sample output 2
5 2 7 4 34 89 1
Open problem
Solution

Let the array a contain the numbers written on the cards. Initialize two pointers: i=0 at the beginning of the array and j=n−1 at its end.

To restore the original sequence, alternately take cards from the left and the right until all elements have been processed. With each selection, the corresponding pointer changes its position: i moves to the right, j moves to the left.

Example

Let’s consider a few steps of the algorithm using the first test case as an example.

Algorithm implementation

Declare an array.

int a[100001];

Read the input data.

scanf("%d", &n);
for (i = 0; i < n; i++)
  scanf("%d", &a[i]);

Set the pointers i=0 and j=n−1.

i = 0; j = n - 1;

While the inequality i≤j holds, alternately print ai​ and aj​, simultaneously moving the pointers.

while (i <= j)
{
  printf("%d ", a[i++]);
  if (i > j) break;
  printf("%d ", a[j--]);
}
Eolymp #11389. Huseyn's game

Huseyn has a string consisting of characters 0 and 1. To entertain himself, he came up with the following game. Huseyn can perform one of two operations on the string:

  • append 0 to the left end, and 1 to the right end;

  • append 0 to the right end, and 1 to the left end;

For example, from the string 010, Huseyn can obtain 00101 or 10100.

You are given a string obtained after all of Huseyn's operations (it is possible that he did not perform any operation). Determine the smallest possible length the string could have initially had.

Input. A single string of length no more than 105, consisting only of characters 0 and 1.

Output. Print the smallest possible length of the string that Huseyn could have initially had.

Sample input 1
01010010
Sample output 1
8
Sample input 2
1001110
Sample output 2
1
Open problem
Solution

Let's consider the input string s — the resulting string after Huseyn has performed all operations. Initialize two pointers: i=0 at the start of the string and j=n−1 at the end.

If si​=sj​, then the characters at the ends of the string are different: either 0 on the left and 1 on the right, or 1 on the left and 0 on the right. This means the previous string could have been extended by applying one of the specified operations. In this case, move both pointers i and j one position towards each other and check again whether the substring s[i...j] could have been obtained through Huseyn's operations.

As soon as the current substring s[i...j] satisfies si​=sj​, it can no longer be produced by the given operations. Print its length — this is the original string that Huseyn had.

Example

Let's perform Huseyn's operations in reverse order.

The string s="1" was originally the one Huseyn had.

Algorithm implementation

Read the input string and calculate its length, storing it in the variable res.

cin >> s;
res = s.size();

Initialize two pointers: i=0 at the start and j=n−1 at the end of the string.

i = 0; j = s.size() - 1;

If si​=sj​, then the characters at the ends of the string are different. Huseyn could have obtained the substring s[i...j] from the substring s[i+1...j−1].

while ((i < j) && (s[i] != s[j]))
{

Move both pointers i and j one position towards each other and decrease the current size res of the substring s[i...j].

  i++; j--;
  res -= 2;
}

Print the answer.

cout << res << endl;
Eolymp #11244. Sum of two

Given an array A, sorted in ascending order and containing n integers. Determine whether there exists a pair of numbers (Ai​,Aj​), where i<j, such that their sum is equal to x.

Input. The first line contains two integers n (n≤105) and x (x≤106). The second line contains n non-negative integers, each of which is not greater than 106.

Output. Print "YES" if such a pair of elements exists, and "NO" otherwise.

Sample input 1
10 13
1 3 5 6 8 10 11 11 11 16
Sample output 1
YES
Sample input 2
8 61
5 5 8 12 16 21 44 50
Sample output 2
NO
Open problem
Solution

Let v be the input array of numbers. Initialize pointers i=0 to the beginning of the array and j=n−1 to the end of the array. The array is already sorted according to the problem conditions.

While pointers i and j do not meet, perform the following actions:

  • If vi​+vj​=x, then the desired pair of elements is found. Print it and terminate the program.

  • If vi​+vj​<x, then move pointer i one position to the right. In this case, the sum vi​+vj​ will increase;

  • If vi​+vj​>x, then move pointer j one position to the left. In this case, the vi​+vj​ will decrease;

Example

Let’s consider the first test. Initialize the pointers. Simulate the algorithm’s operation. The value of x=13, we are looking for two numbers with a sum of 13.

Algorithm implementation

Read the input data.

scanf("%d %d", &n, &x);
v.resize(n);
for (i = 0; i < n; i++)
  scanf("%d", &v[i]);

Initialize the pointers.

int i = 0, j = v.size() - 1;

Move pointer i forward and pointer j backward.

while (i < j)
{

If vi​+vj​=x, then the desired pair of elements is found. Print it and terminate the program.

  if (v[i] + v[j] == x)
  {
    printf("YES\n");
    return 0;
  }

If vi​+vj​<x, then move pointer i one position to the right;

If vi​+vj​>x, then move pointer j one position to the left;

  if (v[i] + v[j] < x) i++; else j--;
}

If the desired pair is not found, print "NO".

printf("NO\n");
Eolymp #11246. Sum of three

Given an array of integers A and an integer x. Find a triplet of numbers (Ai​,Aj​,Ak​) in the array whose sum equals x. All indices i,j,k should be different.

Input. The first line contains the size of the array n (n≤3⋅104) and the value of x (∣x∣≤109). The second line contains n integers, each of which does not exceed 108 in absolute value.

Output. If the required triplet exists, print it in any order. If multiple triplets exist, print any one of them. If the desired triplet does not exist, print −1.

Sample input
8 19
20 3 5 1 15 7 17 12
Sample output
1 3 15
Open problem
Solution

Let a0​,a1​,...,an−1​ be an input array. Iterate through all possible indices k=0,1,...,n−3. Then, for each value of k, find a pair of indices (i,j) such that i>k and ai​+aj​=x−ak​ (i<j). This can be achieved on a sorted array using the two-pointer technique in linear time.

Algorithm implementation

Read the input data.

cin >> n >> x;
v.resize(n);
for (i = 0; i < n; i++)
  cin >> v[i];

Sort the input array.

sort(v.begin(), v.end());

Iterate through the values k=0,1,...,n−3.

for (k = 0; k < n - 2; k++)
{

Find a pair of indices (i,j) such that i>k and vi​+vj​=x−vk​ (i<j). Initialize the indices i and j.

  i = k + 1; j = n - 1;
  s = x - v[k];

Use the two-pointer technique to find the desired pair (i,j).

  while (i < j)
  {
    if (v[i] + v[j] == s)
    {

If the pair (i,j) is found, print the desired triplet of numbers (vk​,vi​,vj​).

      printf("%d %d %d\n", v[k], v[i], v[j]);
      return 0;
    }

If v[i]+v[j]<s, then move pointer i one position to the right;

If v[i]+v[j]>s, then move pointer j one position to the left;

    if (v[i] + v[j] < s) i++; else j--;
  }
}

If the triplet of numbers is not found, print −1.

cout << -1 << endl;
Eolymp #11286. Twice bigger

Given a sorted array A of n integers. For each index i, find the number of elements in the array that lie between Ai​ and 2⋅Ai​ inclusive.

Input. The first line contains the size n (n≤105) of array A. The second line contains n integers, each ranging from 0 to 109, in sorted order.

Output. Print n integers. For each index i (1≤i≤n) of the array, print the number of elements lying between Ai​ and 2⋅Ai​ inclusive.

Sample input
10
1 2 3 4 5 6 7 8 9 10
Sample output
2 3 4 5 6 5 4 3 2 1
Open problem
Solution

The interval A[i...j] will be called good if the numbers in it lie in the range [Ai​;2⋅Ai​] inclusive (meaning Aj​≤2⋅Ai​).

We implement a sliding window using two pointers i and j and maintain it so that the current interval [i...j] is good, while the interval [i...j+1] is bad.

For example, for the following sequence:

  • the intervals [2;2],[2;3],[2;4], and [2;5] are good.

  • the intervals [2;6],[2;7] are bad.

If Aj​≤2⋅Ai​, extend the current interval to А[i...j+1]. Otherwise, reduce it to А[i+1...j]. Before moving the pointer i, print the number of elements lying between Ai​ and 2⋅Ai​ inclusive. It equals j−i.

The algorithm’s complexity is linear, i.e. O(n).

Example

Let’s consider the movement of pointers for the given example.

For the given condition Aj​≤2⋅Ai​, so we move the pointer j forward.

Now Aj​>2⋅Ai​. We need to move the pointer i forward. However, before moving it, print the number of elements lying between Ai​ and 2⋅Ai​ inclusive. It is equal to j−i=6−2=4.

Move j forward until Aj​≤2⋅Ai​.

Now Aj​>2⋅Ai​. Print the answer for i=3 (it equals j−i=8−3=5) and increase i by 1.

Algorithm implementation

Read the input data.

scanf("%d", &n);
for (i = 0; i < n; i++)
  scanf("%d", &a[i]);

Initialize the pointers i=j=0.

i = j = 0;

Move the pointers forward until an answer is found for each value of i<n.

while (i < n) // [i..j]
{

If Aj​≤2⋅Ai​ (and j has not exceeded the array bounds, meaning j<n), extend the current interval by incrementing the pointer j.

  if ((j < n) && (a[j] <= 2 * a[i])) j++;
  else
  {

If Aj​>2⋅Ai​, print the answer for index i and increment i by one.

    printf("%d ", j - i);
    i++;
  }
}
Eolymp #10682. Hotels along the Croatian coast

Along the beautiful Adriatic coast, there are n hotels. Each hotel has its cost in euros. Petr won m euros in the lottery. Now he wants to buy a sequence of consecutive hotels one after another so that the sum of the costs of these consecutive hotels is as large as possible, but does not exceed m.

You need to calculate this maximum possible total cost.

Input. The first line contains two integers n and m (1≤n≤3⋅105,1≤m<231). The next line contains n positive integers less than 106, representing the costs of the hotels in the order they are located along the coast.

Output. Print the desired maximum cost (it will be greater than 0 in all tests).

Sample input
5 12
2 1 3 4 5
Sample output
12
Open problem
Solution

Store the hotel costs in the a array. We’ll call the interval [i...j] good if the sum of hotel costs within it does not exceed m.

Let’s implement a sliding window using two indices i and j, and maintain it so that the current interval [i...j] is good. Let s be the sum of hotel costs within the interval [i...j]. If s+a[j+1]≤m, then expand the current interval to a[i...j+1]. Otherwise, shrink it to a[i+1...j]. Find the maximum among the costs of all considered good intervals.

Example

Consider the movement of pointers for the given example.

  1. When i=0,j moves forward until the sum of numbers in the interval [i...j] does not exceed m=12. Stop at the interval [0...3] because the sum there is equal to 10, while the sum in the interval [0...4] is equal to 15.

  2. When i=1, we cannot move j forward because the sum in the interval [1...4] is equal to 13.

  3. When i=2 move j forward to the interval [2...4].

The maximum value among all good intervals is equal to 12 and is achieved in the interval [2...4].

Algorithm implementation

Read the input data.

scanf("%d %lld", &n, &m);

Initialize the variables:

  • in res, the maximum value among the costs of all processed good intervals is computed;

  • in s, the sum of numbers in the current interval [i...j] is maintained. All the numbers in the current interval [i...j] are stored in the queue q;

s = res = 0;

Process the hotel costs sequentially.

for (i = 0; i < n; i++)
{

Read and add the cost val of the current hotel to the queue.

  scanf("%d", &val);
  q.push(val);

Update the sum s within the interval. All elements of the current interval are stored in the queue q.

  s += val;

If the sum of numbers in the current interval exceeds s, we remove elements from the beginning of the interval.

  while (s > m)
  {
    s -= q.front();
    q.pop();
  }

Compute the maximum value res among the sums of elements in good intervals (where the cost of hotels does not exceed m).

  if (s > res) res = s;
}

Print the answer.

printf("%lld\n", res);
Eolymp #11721. Subarray sums 1

Given an array of n positive integers, find the number of subarrays whose sum is equal to x.

Input. The first line contains the size of the array n (1≤n≤2⋅105) and the target sum x (1≤x≤109). The next line contains n integers a1​,a2​,…,an​ (1≤ai​≤109) — the contents of the array.

Output. Print the required number of subarrays.

Sample input
5 7
2 4 1 2 7
Sample output
3
Open problem
Solution

Let's implement a sliding window using two pointers, i and j. For each fixed i=1,2,..., expand the interval [i...j] as much as possible so that the sum of its elements does not exceed x. In other words, for each i, search for the largest possible j such that the sum of elements in the interval [i...j] does not exceed x, while the sum of elements in the interval [i...j+1] exceeds x.

Let s be the sum of numbers in the interval [i...j]. If s+a[j+1]≤m, expand the interval to [i...j+1]. Otherwise, shrink it to [i+1...j]. Count the number of intervals with a sum of x.

Example

Let's examine the movement of the pointers for the given example.

  1. i=0, j moves forward until the sum of the numbers in the interval [i...j] exceeds x=7. We stop at the interval [0...2], since the sum of the numbers in it is 7, while in the interval [0...3], the sum of the numbers is already 9.

  2. i=1, j moves forward to 3. The sum of the numbers in the interval [1...3] is 7, while in the interval [1...4], it is already 14.

  3. i=2, the considered interval is [2...3]. The sum of the numbers in it is 3, but we cannot move the index j forward because the sum of the numbers in the interval [2...4] is 10, which is greater than x=7.

  4. i=3, the considered interval is [3...3]. The sum of the numbers in it is 2, but we cannot move the index j forward because the sum of the numbers in the interval [3...4] is 9, which is greater than x=7.

  5. i=4, the considered interval is [4...4]. The sum of the numbers in it is 7.

The number of subarrays with a sum of x=7 is 3. They start at indices 0,1, and 4.

Algorithm implementation

Declare an array.

#define MAX 200001
long long a[MAX];

Read the input data.

scanf("%d %lld", &n, &x);
for (i = 0; i < n; i++)
  scanf("%lld", &a[i]);

Initially, set the current interval [i...j]=[0;0]. The sum of the numbers in this interval is s=0.

s = j = 0;

For each value of i, sequentially process the intervals [i...j].

for (i = 0; i < n; i++)
{

For the fixed left end i of the interval [i...j], search for the largest j such that the sum of elements in this interval does not exceed x.

  while ((j < n) && (s + a[j] <= x)) s += a[j++];

If the sum of the numbers s in the current interval [i...j] equals x, increase the desired subarray count cnt by 1.

  if (s == x) cnt++;

Recompute the sum s for the interval [i+1...j].

  s -= a[i];
}

Print the answer.

printf("%lld\n", cnt);
Eolymp #9631. Competition of sequences

Ziya will take part in the sequence competition tomorrow. The number x≥0 is called the top of some sequence if the sequence 1,2,3,...,x−1,x,x−1,...,3,2,1 is a subsequence of this sequence. The strength of each sequence is considered to be its largest vertex.

Tomorrow all students will go to the competition and the winner of the strongest sequence will be the winner. Zia has the sequence a1​,a2​,a3​,...,an​. He wants to take over the competition scoring system and remove sequences from it with more force than himself. However, Zia does not know the power of his own consistency, but really wants to win. Help him calculate the strength of his own sequence.

Input. The first line contains the number n (1≤n≤105) of numbers in Zia's sequence. The next line contains n integers ai​ (1≤ai​≤105) — the elements of the sequence.

Output. Print one number — the strength of the given sequence.

Sample input 1
2
2 10
Sample output 1
0
Sample input 2
3
1 2 3
Sample output 2
1
Sample input 3
5
1 10 2 3 1
Sample output 3
2
Open problem
Solution

Let v be the input array of numbers. Initialize the pointers i=0 at the beginning of the array and j=n−1 at the end of the array. We will count the strength of the sequence in the variable k. Initially, set k=1.

While the pointers i and j do not meet, perform the following actions:

  1. Move the pointer i one position to the right if it does not point to the number k.

  2. Move the pointer j one position to the left if it does not point to the number k.

  3. If both pointers point to the number k, increase k by one and move each pointer one position in the corresponding direction.

After the algorithm completes, the answer will be the value k−1.

Example

Consider the second test. Initialize the pointers. Move the pointer i to the right and the pointer j to the left until they both point to the number 1.

Move the pointer i to the right and the pointer j to the left until they both point to the number 2.

The pointers meet, we stop the algorithm. The answer will be the value k=2.

Algorithm implementation

Read the input data.

scanf("%d", &n);
v.resize(n);
for (i = 0; i < n; i++)
  scanf("%d", &v[i]);

Set the pointers to the start and end of the array v.

int i = 0, j = v.size() - 1;

In the variable k, we count the strength of the sequence.

k = 1;
while (i <= j)
{

Move the pointer i to the right until it encounters the number k.

  if (v[i] != k) i++;

Move the pointer j to the left until it encounters the number k.

  if (v[j] != k) j--;

If both pointers point to the number k, then increase k by one.

  if (v[i] == k && v[j] == k) k++;
}

Print the answer.

printf("%d\n", k - 1);
Eolymp #9632. The best team

Today, n programmers have gathered. Each programmer has a rating that reflects his strength. The rating is an integer between 0 and 109. Your rating as a programmer is m. From all the programmers gathered today, you want to choose two for your team. They must be selected in such a way that their total rating is maximized but does not exceed your rating, as you want to be the leader of this team.

Input. The first line contains two integers: n (2≤n≤105) — the number of programmers, and m (0≤m≤109) — your rating. The second line contains n integers r1​,r2​,...,rn​ (0≤ri​≤109) — the ratings of the programmers.

Output. Print a single integer — the maximum sum of the ratings of the selected programmers, or −1 if it is impossible to find such two people.

Sample input 1
5 8
5 3 4 6 5
Sample output 1
8
Sample input 2
7 19
8 4 25 1 20 5 12
Sample output 2
17
Sample input 3
4 76
38 41 39 40
Sample output 3
-1
Open problem
Solution

Sort the programmers' ratings in the array v. To find two programmers with the maximum total rating, we'll use the two-pointer technique.

Initialize the pointer low=0 at the beginning of the array and the pointer high=n−1 at the end of the array.

Among all possible sums v[low]+v[high], not exceeding m, find the maximum. If v[low]+v[high]≤m, move the low pointer forward. Otherwise, move the high pointer backward. Continue this process until the pointers meet.

Example

Let's consider the second test. Sort the numbers and initialize the pointers. Simulate the algorithm's execution. In this case, m=19: we are looking for two numbers with the maximum sum that does not exceed 19.

Algorithm implementation

Read the input data.

scanf("%d %d", &n, &m);
v.resize(n);
for (i = 0; i < n; i++)
  scanf("%d", &v[i]);

Sort the programmers’ ratings.

sort(v.begin(), v.end());

Initialize the pointers. The variable mx stores the maximum sum of two elements.

int mx = -1, low = 0, high = n - 1;

The pointer low is moved forward, and the pointer high is moved backward.

while (low < high)
{

Among all possible sums v[low]+v[high] that do not exceed m find the maximum. If v[low]+v[high]≤m, move low forward. Otherwise, move high backward.

  if (v[low] + v[high] <= m)
  {
    mx = max(mx, v[low] + v[high]);
    low++;
  }
  else high--;
}
C++
7 lines
108 bytes

Print the answer.

printf("%d\n", mx);
Eolymp #10568. Diamond Collector (Bronze)

Bessie the cow, always a fan of shiny objects, has taken up a hobby of mining diamonds in her spare time! She has collected n diamonds of varying sizes, and she wants to arrange some of them in a display case in the barn.

Since Bessie wants the diamonds in the case to be relatively similar in size, she decides that she will not include two diamonds in the case if their sizes differ by more than k (two diamonds can be displayed together in the case if their sizes differ by exactly k). Given k, help Bessie determine the maximum number of diamonds she can display in the case.

Input. The first line contains n (n≤1000) and k (0≤k≤10000). The next n lines each contain an integer giving the size of one of the diamonds. All sizes will be positive and will not exceed 10000.

Output. Print the maximum number of diamonds that Bessie can showcase.

Sample input
5 3
1
6
4
3
1
Sample output
4
Open problem
Solution

Sort the array of diamond sizes. For each index i, consider the sequence mi​,mi+1​,...,mj​ such that ∣mj​−mi​∣≤k, but at the same time, ∣mj+1​−mi​∣>k. Among all such sequences, find the one that contains the largest number of elements.

Example

Sort the sizes of the diamonds.

Consider the interval [0;3]. The difference between the sizes of the diamonds in this interval does not exceed k=3. However, Bessie will not be able to showcase all the diamonds in the interval [0;4] in the barn, since m4​−m0​>3.

Algorithm implementation

Declare an array to store the sizes of the diamonds.

int m[1000];

Read the input data.

scanf("%d %d", &n, &k);
for (i = 0; i < n; i++)
  scanf("%d", &m[i]);

Sort the array.

sort(m, m + n);

The maximum number of diamonds that Bessie can display in the barn is counted in the variable res.

res = 0;

For each index i, consider the sequence mi​,mi+1​,...,mj​ of the greatest length such that ∣mj​−mi​∣≤k. Count the length of this sequence in the variable cnt.

for (i = 0; i < n; i++)
{
  cnt = 0;
  for (j = i; j < n; j++)
  {

As soon as the condition ∣mj​−mi​∣>k becomes true, exit the loop.

    if (m[j] > m[i] + k) break;
    cnt++;
  }

Among the lengths of all sequences, find the maximum.

  if (cnt > res) res = cnt;
}

Print the answer.

printf("%d\n", res);
Eolymp #11247. Container With Most Water

There is an array h of integers of length n, representing the heights of n vertical lines. For each i-th line, its endpoints are defined by the coordinates (i,0) and (i,hi​).

Find two lines that, together with the x-axis, form a container capable of holding the maximum amount of water.

Input. The first line contains the size n (n≤105) of the array h. The second line contains n positive integers, the elements of the array h, each of which does not exceed 109.

Output. Print the maximum volume of water that the container can hold.

Sample input
9
1 8 6 2 5 4 8 3 7
Sample output
49
Open problem
Solution

First, compute the volume of water in the container formed by the outermost vertical lines, i.e., between the lines of the pair (l,r)=(1,n). Then, move the pointers l and r towards each other:

  • if hl​<hr​, increase l by 1;

  • if hl​≥hr​, decrease r by 1;

The volume of water between the lines l and r is equal to min(hl​,hr​)∗(r−l). Among all the calculated values, find the maximum.

The problem can be solved in O(n2). However, due to the constraint n≤105, such a solution would result in a time limit exceeded (TLE). It is sufficient to iterate over the pairs of lines (i,j), where 1≤i<j≤n, and for each such pair, calculate the volume of water they can hold. Among all the computed values, find the maximum volume.

Example

The container from the first test looks like this:

The maximum amount of water can be held between the lines 2 and 9. The water level height is 7, and the volume of water is 7⋅7=49.

Algorithm implementation

Read the input data.

scanf("%d", &n);
h.resize(n);
for (i = 0; i < n; i++)
  scanf("%lld", &h[i]);

Store the maximum amount of water the container can hold in the variable res.

long long res = 0;

Initialize two pointers (l,r)=(1,n).

int l = 0, r = h.size() - 1;

Move the pointers l and r towards each other until they meet.

while (l < r)
{

The volume of water between the lines l and r is equal to min(hl​,hr​)⋅(r−l). Among all such volumes, find the maximum.

  res = max(res, min(h[l], h[r]) * (r - l));

Move the pointers.

  if (h[l] < h[r])
    l += 1;
  else
    r -= 1;
}

Print the answer.

printf("%lld\n", res);
Eolymp #11340. Radio 106 FM

You are given a list of songs that played on Radio 106 FM. The list contains a total of n songs. Find the length of the longest fragment of the list that consists of non-repeating songs.

Input. The first line contains the number of songs n (1≤n≤105) in the list. The second line contains n integers k1​,k2​,...,kn​ (1≤ki​≤109), which are the identification numbers of the songs.

Output. Print the length of the longest fragment of the list that consists of unique songs.

Sample input 1
8
1 2 1 3 2 7 4 2
Sample output 1
5
Sample input 2
4
1 1 2 1
Sample output 2
2
Open problem
Solution

Let the array v store the identification numbers of the songs. Using two pointers, we will maintain a sliding window [i;j] in which the songs do not repeat. In other words, all the songs in the segment [i;j] are unique. The songs from this segment will be stored in a set s. For each value of i, we will try to extend the segment to the maximum possible length. That is, for a fixed i, we will search for such a j that in the segment [i;j] the songs do not repeat, but in the segment [i;j+1] duplicates already appear.

When processing the current song at index j+1, there are two possible cases:

  • If the song vj+1​ is not present in the segment [i;j], add it to this segment, extending it to [i;j+1];

  • If the song vj+1​ is already present in the segment, shift the left boundary i to the right until vj+1​ disappears from the segment [i;j]. Then, add vj+1​ to the segment, extending it to [i;j+1]. With each shift of i, remove the corresponding elements from the set s;

Among all possible segments [i;j] with unique songs, find the maximum length. This will be the answer to the problem.

Example

Let’s consider how the segments with unique songs will change for the first example.

The length of the longest segment is 5.

Algorithm implementation

Read the input data. The identification numbers of the songs are stored in the array v.

scanf("%d", &n);
v.resize(n);
for (i = 0; i < n; i++)
  scanf("%d", &v[i]);

Maintain the segment [i;j−1] of unique songs (i.e., the songs from vi​ to vj−1​ do not repeat). In the set s, store the identification numbers of the songs from this segment. The variable res tracks the length of the longest fragment with unique songs.

i = res = 0;
for (j = 0; j < n; j++)
{

Consider the current song at index j. If it is already in the set s, it will not be possible to extend the current segment [i;j−1] by including the j-th song. In this case, we need to shift the left boundary i, removing the song vi​ from the set s, until the j-th song disappears from the set s.

  while (s.find(v[j]) != s.end())
  {
    s.erase(v[i]);
    i++;
  }

Add the j-th song to the segment and, accordingly, to the set s. Thus, the segment [i;j] will not contain any repeated songs.

  s.insert(v[j]);

Among all possible segments [i;j], find the longest one. The length of the segment [i;j] is j−i+1.

  res = max(res, j - i + 1);
}

Print the answer.

printf("%d\n", res);

List of problems

  • 2098. Invertor

  • 11387. Cards game

  • 11388. Cards game 2

  • 11389. Huseyn's game

  • 11244. Sum of two

  • 11246. Sum of three

  • 11286. Twice bigger

  • 10682. Hotels along the Croatian coast

  • 11721. Subarray sums 1

  • 9631. Competition of sequences

  • 9632. The best team

  • 10568. Diamond collector (bronze)

  • 11247. Container with most water

  • 11340. Radio 106 FM


17

Comments (5)

Loading

Just a moment, getting data from the server
azimzadenihad•5 months ago

thanks for all

0
Eltaj13•6 months ago

Thanks for the problems!

1
drizzy•6 months ago

Thanks for the problems! Will there be future topic contests like these ?

2
medv•6 months ago•2 revision

drizzy Thanks a lot if you liked it. By the way, problems "Competition of sequences", "The best team" and "Radio 106 FM" are taken from the past official Azerbaijan School Competitions

7
drizzy•6 months ago

medv Please continue this series of topic wise contests. Thanks

4