CodeChef conducted Starters 58 on 28th September. Most problems for DIV 4 were array based.
Problems
Reach The Target
Problem
- There is a cricket match going on. Team B is batting second with a target of
X runs
. Team B's current score isY runs
. How many runs more does Team B require to win the match? (In cricket, target is 1 more than the score of team batting first).
Input
- First line contains single integer T, denoting number of test cases.
- Each test case consists of 2 space separated integers X and Y ( X is target, Y current score).
Output Format
- For each case, output how many more runs team B should score to win.
Constraints
- 1 ≤ T ≤ 10
- 50 ≤ Y ≤ X ≤ 200
Sample
- If X = 200 and Y = 50, team B should score 150 more runs to win.
Algorithmic solution
- For any pair of X,Y the amount of runs needed is equal to the difference of the target and current score.
Code solution (c++)
#include <iostream>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t,x,y;
cin>>t;
while (t--){
cin>>x>>y;
cout<<x-y<<"\n";
}
}
Ranklist Pages
Problem
- Chef participated in an exam and got a rank X. He wants to find his name in the ranklist, but there are too many pages to search, and each page contains 25 participant marks. Chef wants to find the exact page number containing his info. Find the page number.
Input
- First line contains single integer T, denoting number of test cases.
- Each test case consists of single integer X, Chef's rank.
Output
- For each testcase, output on newline the page number containing Chef's name.
Constraints
- 1 ≤ T ≤ 1000
- 1 ≤ X ≤ 1000
Sample
- If Chef's rank is 132, his name is on page 6
- If Chef's rank is 34, his name is on page 2
Algorithmic Solution
- Each page contains 25 names. If X is a multiple of 25, then his name will be the last on a given page. The number of pages can be counted in units of 25, i.e
This operation can be done without loops using integer division.let a = x pages = 0 while (a > 25){ a = a-25 pages = pages + 1 } pages = pages + 1
Integer division returns only the integer part of the quotient, and discards the fractional part.
For example, when X is 77, x/25 is 3 (25 * 3 == 75), and the fractional part is discarded. The page number will be one more than quotient: in above case, the first 3 pages go up to rank 75 and page 4
contains rank 77.
Code Solution (C++)
#include <iostream>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t,x,w;
cin>>t;
while (t--){
cin>>x;
w = x/25;
if (x%25 != 0)
w++;
cout<<w<<"\n";
}
}
Remove Bad Elements
Problem
- Chef has an array A of length N. He wants to make all the elements of the array the same. The only allowed operation is removal of one element at a time from the array. Determine the minimum number of operations required to make all the array elements have the same value.
Input
- First line contains integer T, number of Test cases.
- First line of every testcase contains single integer N, the size of array A
- Second line contains N space separated integers denoting array A.
Output
- For each case, output the minimum number of operations required to make all elements same.
Constraints
- 1 ≤ T ≤ 4000
- 1 ≤ N ≤ 105
- 1 ≤ Ai ≤ N
Sample
Sample input :
3 3 4 3
Sample Output
1
Algorithmic Solution
- In an array containing N elements, if you wish to make all elements same by removing one element at a time in minimum steps, you should remove only those elements which are repeated less than the max repeated element. If :
- N = 10
- A = [1 ,2, 2 ,1 ,2 ,3 ,2 ,1 ,2 ,3]
- We can remove all non
1
elements in 7 steps, all non3
elements in 8 steps, and all non2
elements in 5 steps. This is because max_repeated element is 2. - The output doesn't require we know anything about the order of the elements, so it is not necessary to store the elements, only count the frequency of the elements.
//for each test case
find the number of elements : n
find the maximum frequency among all elements : m
minimum number of items to be removed = n - m
Code Solution (C++)
#include<bits/stdc++.h>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t,n,k,l;
cin>>t;
while (t--){
cin>>n;
vector <int> numbers(n+1,0);
for (int i = 0; i < n;i++){
cin>>k;
numbers[k]++;
}
sort(numbers.begin(),numbers.end());
l = numbers[n];
cout<<n-l<<"\n";
}
}
Break the elements
Problem
- Chef has an array of integers of length N. In one operation, he can take any element and break it into two integers. This operation can be performed any number of times. After each operation, the number of elements in array increases by 1.
- We need to determine the minimum number of such operations required to make the
parity
of all array elements the same.Parity refers to the property of a number being odd/even.
Input
- First line of input contains T, the number of test cases.
- The first line of each testcase contains N, the number of elements in array.
- The second line of each test case contains N space separated integers A1, A2, ... , An.
Output
- For each test case, output the minimum number of operations required to make all the elements have same parity.
Constraints
- 1 ≤ T ≤ 4000
- 1 ≤ N ≤ 105
- 1 ≤ Ai ≤ 109
- Sum of N does not exceed 2 . 105
Sample
- Sample 1
Input: 4 1 3 2 7 Output: 1
- Sample 2
Input: 5 2 4 6 8 1 Output: 4
Algorithmic Solution
The problem may be a bit tricky if you don't think out the entire problem. At first glance, it seems we need to change the parity of the even/odd elements depending on which ones are more. But that is a mistake!
Consider the pattern in which odd/even numbers can be split into two:
even = odd + odd
odd = even + odd
Regardless of how many times we carry out the operations, we can never
be rid of odd numbers! Thus, if we want a uniform parity array, we need to change x
even numbers into odd numbers. Thus instead of a complicated logic requiring cases etc, just count the number of even numbers in the array!
IF number of evens is 0, answer is 0.
IF number of evens is k, answer is k.
IF number of evens is n (all are even), answer is zero.
Use %
operator to achieve the final zero.
Code Solution (C++)
#include <bits/stdc++.h>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t,i;
long long n,e,k;
cin>>t;
while (t--){
cin>>n;
e = 0;
for (i=0; i<n;i++){
cin>>k;
if (k&1)
continue;
else
e++;
}
cout<<e%n<<"\n";
}
}
Add To Subsequence
Problem
- Chef has an array of size N. He wants to make all the array elements distinct. He can perform the following operation:
take any subsequence of array, and add any constant k to subsequence elements
. He can carry out the operation any number of times. - Find the minimum times he needs to carry out the operation to get distinct elements
Subsequence means choosing any k elements of array, for instance {1,3,5} is a subsequence of {1,2,3,4,5}.
Input
- First line of input contains integer T, the number of test cases.
- First line of each test case contains integer N, the size of array
- Second line contains N space separated integer members of array
Output
- For each test case, output on new line the minimum number of operations required to make the array distinct.
Constraints
- 1 ≤ T ≤ 4000.
- 1 ≤ N ≤ 2 . 105.
- 1≤ Ai ≤ 109.
- Sum of N over all test cases does not exceed 3 * 105.
Sample
- Testcase 1
Input: 3 3 3 3 Output: 2
Testcase 2
Input: 5 1 3 2 4 6 Output: 0
Testcase 3
Input: 10 1 5 3 1 6 1 1 7 2 1 Output: 3
Algorithmic Solution
- At first glance it is obvious that the minimum number of operations is in some way dependent on the frequency of the max repeated element.
- The first assumption is the minimum number of operations is
max_freq - 1
, because if 5 elements have same value, we need to change atleast 4. This thinking is reinforced if you look at testcase 1, where max_freq is 3 and the answer is 2. But for testcase 3, the maximum frequency is 5 (5 1's in array), but the answer is 3?! How? - At any operation on the array, we can change any number of elements. For optimal steps, we choose a subsequence containing half the elements in random order and add some high-value constant. Then we add another high value constant to another random subsequence. In this way, we can change the elements till they are distinct.
Consider Testcase 3
N = 10 , A = [1,5, 3, 1, 6, 1, 1, 7, 2, 1].
If we choose subsequence of first 5 elements and add 10, we get:
A = [11,15,13,11,16,1,1,7,2,1]
Now choose subsequence A45678 and add 15:
A = [11,15,13,26,31,16,16,22,2,1]
Now choose subsequence A278910 and add 20:
A = [11,35,13,26,31,16,36,42,22,21]
As we can see, in 3 steps we have made the array distinct. MAXFREQ-1 is 4, so our earlier assumption was wrong.
- The minimum number of operations is equal to the number of times max_frequency can be divided by 2, such that it is greater than 1. Instead of looping and dividing to find this number, remember the property of
log
!
- log of a to the base b is the number of times a can be divided by b till (a < b).
- Thus log of 16 to base 2 is 4, because 16/2 is 8, 8/2 is 4, 4/2 is 2 and 2/2 is one (1 is less than 2).
- Thus to determine the number of times max_freq can be divided, we have to take its log2. Take care that log gives floating-point values, and its answer needs to be rounded up.
- For example, minimum number of operations required for test case 3 is 3, but log2(5) IS 2.3212! Using integers in this would give answer 2, when the correct answer is 3. Thus, we need to use ceil operation to round up the value given by log2.
Code Solution (C++)
#include <bits/stdc++.h>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t,n, i,x,maxF;
cin>>t;
while (t--){
cin>>n;
/*
Algo:
have to take n numbers
calculate the frequencies
find the max frequency element
answer will be number of times the max_freq needs
to be divided into two to get 1, or log2(mf)
answer is one more than log2(mf) (by pattern)
log2 returns double so use ceil function to go one up
*/
map <int,int> freq;
for (i = 0; i < n;i++){
cin>>x; //take the number
freq[x]++;
}
maxF = 0;
for (auto y:freq){
maxF = max(maxF,y.second);
}
cout<<ceil(log2(maxF))<<"\n";
}
}
Conclusion
Starters 58 was a challenging experience! Once the first four problems were done (in about 66 minutes), I sat and tried to solve the remaining 3. I tried approaches, changed up, fixed bugs, and did everything I could but failed. Managed to solve AddtoSubsequence after the contest. Got good practice with challenging problems !