Advertisement
glays

CP Coaching Week 1 (20 -> 26 November 2019) - Solutions

Nov 20th, 2019
253
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.47 KB | None | 0 0
  1. Problem 1:
  2. You may have solved this with a naive approach, where you loop from i to j and calculate the sum in each query.
  3. But that has a Big-O complexity of O(N*Q) which "should" cause a TimeLimitExceeded; the test data are weak.
  4.  
  5. Let's discuss a much faster solution, using prefix sum arrays.
  6. Learn this technique here: hackerrank.com/topics/prefix-sum
  7.  
  8. A prefix of something is a part of it that begins at the beginning.
  9. For example "ab", "a", "abc" are prefixes of the string "abc".
  10. The trick is to construct a prefix sum array P, where P[i] = A[0] + A[1] + ... + A[i] -- A is the input array
  11. Using this array, any sum A[i] + A[i+1] + ... + A[j] can be represented using P as P[j] - P[i-1]. Be careful from the case where i = 0.
  12.  
  13. Re-submit the problem using this method!
  14. And then try to solve this: codeforces.com/contest/816/problem/B
  15.  
  16.  
  17.  
  18. Problem 2:
  19. The key observation to make is that the valleys will be disjoint, so you can keep a counter and count each time
  20. you go back to level 0 while coming up from -1.
  21.  
  22. #include <bits/stdc++.h>
  23. using namespace std;
  24. int main(){
  25. int n; cin >> n;
  26. string s; cin >> s;
  27. int nb = 0;
  28. int currentLevel = 0;
  29. for(int i=0;i<n;++i){
  30. if(s[i] == 'D') --currentLevel;
  31. else{
  32. ++currentLevel;
  33. if(currentLevel == 0) ++nb;
  34. }
  35. }
  36. cout << nb << endl;
  37. }
  38.  
  39.  
  40.  
  41. Problem 3:
  42. We are looking for the maximum sized set S of numbers from the array, such that the absolute difference between any two of the chosen integers is less than or equal to 1. Meaning S = {x,x,x,x.....,x+1,x+1,x+1,x+1....} for some x in the array. ==> There will only be two consecutive numbers in it.
  43. We can keep the occurence of each number, test all the possibilities and take the maximum.
  44.  
  45. #include <bits/stdc++.h>
  46. using namespace std;
  47. int occurence[100]; // things declared globally(outside the main()) are automatically set to 0
  48. int main(){
  49. int n; cin>>n;
  50. for(int i=0; i<n; i++){
  51. int x; cin>>x;
  52. ++occurence[x];
  53. }
  54. int answer = 0;
  55. for(int i=1; i+1<=99; i++) answer = max(answer, occurence[i] + occurence[i+1]);
  56. cout << answer << "\n";
  57. return 0;
  58. }
  59.  
  60.  
  61.  
  62. Problem 4:
  63. Let p and q the two numbers that give us the minimal abs(p-q).
  64. If we sort the array, p and q will be adjacent. Try to demonstrate why, by yourself. (par l'absurde)
  65. So we just sort the array and check every two adjacent numbers and take the minimum.
  66.  
  67. #include <bits/stdc++.h>
  68. using namespace std;
  69. const int inf = 2e9;
  70. int main() {
  71. int n; cin >> n;
  72. int a[n]; for(int i=0; i<n; ++i) cin >> a[i];
  73. sort(a, a + n);
  74. int answer = inf;
  75. for(int i=0; i + 1 < n; ++i) answer = min(answer, abs(a[i] - a[i + 1]));
  76. cout << answer << "\n";
  77. return 0;
  78. }
  79.  
  80.  
  81.  
  82.  
  83. Problem 5:
  84. (Can be solved by std::set but we haven't studied it yet; although you can read about it in the handbook)
  85. Straight forward using a boolean array.
  86.  
  87. #include <bits/stdc++.h>
  88. using namespace std;
  89. bool canWin[101]; // initialized automatically to false because it's declared globally
  90. int main() {
  91. int n; cin>>n;
  92.  
  93. int p; cin>>p;
  94. for(i=1; i<=p; i++){
  95. int x; cin>>x; canWin[x] = true;
  96. }
  97.  
  98. int q; cin>>q;
  99. for(i=1; i<=q; i++){
  100. int x; cin>>x; canWin[x] = true;
  101. }
  102.  
  103. for(i=1; i<=n; i++) if(!canWin[i]){
  104. cout<<"Oh, my keyboard!\n";
  105. return 0;
  106. }
  107. cout<<"I become the guy.\n";
  108.  
  109. return 0;
  110. }
  111.  
  112.  
  113.  
  114. Problem 6:
  115. It's not hard to see that the optimal way is to bring the leftmost maximum number to the front,
  116. and the rightmost minimum number to the end.
  117. How much time will those swap operations take?
  118. Let a be the index of the leftmost maximum, and b be the index of the rightmost minimum. (1 indexed indices)
  119. We will need a-1 "seconds" and n-b "seconds". Is that all?
  120.  
  121. No. Imagine the case where a>b. In that case, we will need one less operation to move the second after fixing the first.
  122. Try to figure out why with an example.
  123.  
  124.  
  125. #include <bits/stdc++.h>
  126. using namespace std;
  127. int main() {
  128. int n; cin>>n;
  129. int t[n + 1];
  130. for(int i=1; i<=n; i++) cin>>t[i];
  131.  
  132. int mx = *max_element(t+1, t+1+n); // if you're doing it 0-indexed, the array's range will be (t,t+n) as usual
  133. int a; for(int i=n; i>=1; --i) if(t[i] == mx) a = i;
  134.  
  135. int mn = *min_element(t+1, t+1+n);
  136. int b; for(int i=1; i<=n; ++i) if(t[i] == mn) b = i;
  137.  
  138. cout << a-1 + n-b - (a > b) << "\n";
  139.  
  140. return 0;
  141. }
  142.  
  143.  
  144. Remember to solve the dummy contest's problems!! ==> codeforces.com/group/MAbng8L9pC/contest/257241
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement