Here is the mashup link (the problems are from Codeforces' problem set).
A. Split The Data
Let's sort the array in nonincreasing order. Now the answer is some of the first flash-drives. Let's iterate over array from left to right until the moment when we will have the sum at least m. The number of elements we took is the answer to the problem. Complexity: $$$O(nlogn)$$$.
n = int(input())
m = int(input())
flash = []
for _ in range(n):
val = int(input())
flash.append(val)
flash.sort(reverse=True)
cur = 0
for i in range(n):
cur += flash[i]
if cur >= m:
print(i + 1)
break
B. Yet Another Reordering
The goal is to find a greater element for each element in our array. So, consider sorting the array to achieve this.
If our array consists of unique elements, the answer will always be $$$N - 1$$$ (where $$$N$$$ is the size of our array).
Preserve the larger numbers to represent their preceding larger numbers.
As mentioned in the hints, If our array consisted of unique elements, the answer would always be N — 1, where N is the size of our array. Here’s why:
- After sorting the array, for every number in our array, the next number can always replace it because it will always be greater than it, except for the last (maximum) number.
- So, we can safely replace all elements except the largest one.
Handling Duplicates:
To handle duplicates, we’ll use two pointers: left and right. Left represents the current smaller number that needs to be replaced. Right represents the current immediate larger element compared to the first number. We’ll greedily choose the next immediate larger element for the smaller number. This ensures that we have a larger number greater than the smaller one to replace it.
N = int(input())
arr = list(map(int, input().split()))
arr.sort()
left = 0
for right in range(N):
if arr[right] > arr[left]:
left += 1
print(left)
C. I love Minimization
Suppose we have an array $$$a$$$ that we want to construct, with elements $$$a_{1},a_{2},…,a_{n}$$$. To simplify the process, let's assume that the elements of a are sorted in non-decreasing order, meaning $$$a_{1}≤a_{2}≤⋯≤a_{n}$$$.
Let's start with $$$a_{1}$$$. Since the elements of $$$a$$$ are sorted, the pairs $$$(a_{1},a_{2}),(a_{1},a_{3}),…,(a_{1},a_{n})$$$ will have $$$a_{1}$$$ as the smallest element in each pair. Therefore, the number of occurrences of $$$a_{1}$$$ in array b will be $$$n−1$$$.
Moving on to $$$a_{2}$$$, we already know that $$$a_{1}$$$ appears $$$n−1$$$ times in $$$b$$$. Since the elements of $$$a$$$ are sorted, all pairs involving $$$a_{2}$$$ will have $$$a_{2}$$$ as the second smallest element. This means $$$a_{2}$$$ will appear $$$n−2$$$ times in array $$$b$$$.
We continue this process for each element $$$a_{i}$$$ in $$$a$$$. The number of occurrences of $$$a_{i}$$$ in array $$$b$$$ will be $$$n−i$$$.
We can't determine the exact value of $$$a_{n}$$$, because it won't be written to array $$$b$$$. Therefore, for an we can choose any number in the range $$$[a_{n−1};10^9]$$$.
In case there are multiple elements $$$b_{i}$$$ in array $$$b$$$ that satisfy the condition for a particular $$$a_{i}$$$, we choose the smallest $$$b_{i}$$$. This greedy approach works, because we are constructing $$$a$$$ in non-decreasing order.
t = int(input())
for _ in range(t):
n = int(input())
nums = list(map(int,input().split()))
nums.sort()
ans = []
c = n - 1
i = 0
while i < len(nums):
ans.append(nums[i])
i += c
c -= 1
ans.append(10**9)
print(*ans)
D. Beautiful Sequences
For every number in a sequence, we can store the sum of the sequence with that number removed in a hashmap.
Storing a sum with a number removed is computed for every number, so the space complexity will be linear. As a value for each difference we will store the index of the sequence and the index of the sum within the sequence. This way if we find the same sum in another sequence, we will have access to the required answer.
k = int(input())
sequences = []
for _ in range(k):
n = int(input())
a = list(map(int, input().split()))
sequences.append(a)
encountered_sums = {}
for j in range(k):
sequence = sequences[j]
seq_tot = sum(sequence)
for y in range(len(sequence)):
dif = seq_tot - sequence[y]
# if the difference exists it shouldn't be in the same sequence
if dif in encountered_sums and encountered_sums[dif][0] != j:
# i = the sequence index where we saw this dif before, x the index of the number removed to get this sum in sequence i
i, x = encountered_sums[dif]
print('YES')
print(i + 1, x + 1)
print(j + 1, y + 1)
exit()
# store the sequence sum with the current number excluded
encountered_sums[dif] = (j, y)
print('NO')
E. Interesting String
To determine the order of removals, we start from the end of the string. The last character represents the latest removed character. Moving backward, when encountering a character not seen before, it implies that this character was removed in the next step. Thus, we initiate the process from the last character, and each new character encountered denotes the one removed prior. Once we establish this order, we need to reverse it. Now that we have the removal order, the next step is to verify whether the resulting string could have originated from that order. To check this, we first need to assess whether the character counts are valid. If a character was removed first, its actual occurrence in the original string should match its count in the given string. If removed second, the real occurrence in the original string is the count in the given string divided by 2, and so on. After obtaining the counts for each character in the original string, if the sum yields a non-integer number, the given string is invalid. However, if it results in an integer, we proceed to check if the given string can be derived from the first $$$k$$$ characters of the original string $$$k$$$ representing the sum of the counts. To do this, we perform the same operations on the word containing the first $$$k$$$ characters of the given string. After obtaining the result, we compare it with the given string. If they match, we can confidently print the obtained removal order and the original string (which is the first $$$k$$$ characters of the given string). If not, we print $$$-1$$$ as the given string is not valid.
t = int(input())
for _ in range(t):
s = input()
arr = []
got = set()
count = Counter(s)
for i in s[::-1]:
if i not in got:
arr.append(i)
got.add(i)
arr.reverse()
occur = []
pos = 1
for i in range(len(arr)):
occur.append(count[arr[i]] / (i + 1))
left = 0
if math.ceil(sum(occur)) != int(sum(occur)):
pos = 0
if pos:
ans = ""
cur = s[:int(sum(occur))]
j = 0
while cur:
ans += cur
stk = ""
for i in cur:
if i != arr[j]:
stk += i
cur = stk
j += 1
if ans != s:
pos = 0
if pos:
print(s[:int(sum(occur))],"".join(arr))
else:
print(-1)