-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added editorials for summer contest 2021
- Loading branch information
1 parent
09e896b
commit b09bb46
Showing
15 changed files
with
9,607 additions
and
2,341 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
Tags: Heaps | ||
|
||
The node with the minimum cumulative distance would be the one right in the centre. | ||
That node would essentially be the median node based on its distance value. | ||
|
||
The problem's now reduced to keeping track of the median of a list that's being updated. | ||
|
||
Given a list, sorted in ascending order, if we were to know the largest element of the left half of the list, and the smallest element of the right half, we could determine the median of that list. | ||
|
||
Implementation | ||
|
||
To achieve what's required, we could maintian two heaps, a max heap for the left half, and a min heap for the right. | ||
Each number could be added into one of the two heaps, and the sizes of the heaps could be balanced to make sure they're storing two halves of the current sequence. | ||
|
||
Initialize a max-heap left, and a min-heap right | ||
1. If the number is greater than the top of left, it belongs to right, otherwise it belongs to left | ||
2. In case the difference in size of the two heaps exceeds 2, the top of either right or left could be shifted to the other heap. (This way, it's guarranteed the size of the two heaps would be equal if there are an even number of elements in the current sequence, or the sizes would differ by exactly 1 in case the sequence size is odd.) | ||
3. Since the heaps are always balanced relative to each other, the top of the larger heap will always correspond to the median of the sequence. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include<bits/stdc++.h> | ||
using namespace std; | ||
|
||
void addNode(priority_queue<pair<int, int> >& left, | ||
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int> > >& right, int x, int v) { | ||
pair<int, int> node = { v, x }; | ||
if(node > left.top()) | ||
right.push(node); | ||
else | ||
left.push(node); | ||
if (left.size() > right.size() + 1) { | ||
right.push(left.top()); | ||
left.pop(); | ||
} else if (right.size() > left.size() + 1) { | ||
left.push(right.top()); | ||
right.pop(); | ||
} | ||
} | ||
|
||
int main() { | ||
int d, x, v; | ||
cin >> d; | ||
cin >> x >> v; | ||
|
||
priority_queue<pair<int, int> > left; | ||
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int> > > right; | ||
|
||
left.push({ v, x }); | ||
|
||
for(int i = 0; i < d; ++i) { | ||
cin >> x >> v; | ||
addNode(left, right, x, v); | ||
cin >> x >> v; | ||
addNode(left, right, x, v); | ||
if (left.size() > right.size()) | ||
cout << left.top().second << "\n"; | ||
else | ||
cout << right.top().second << "\n"; | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
We can look at the problem as a graph problem, where each student is a node and each friendship is an edge. | ||
|
||
Here the problem requires a bipartite graph check where each group ruby and emerald can be considered as colors to be assigned to nodes. We need to check if the given graph is bipartite. | ||
|
||
One way to do this is to run a dfs from a node and assign a color to it. Then all its children must be assigned an opposite color. | ||
While runnning the dfs, if we have already visited a child, we must check if it has the same color as its parent. | ||
If it does, then it is impossible to color the graph in a bipartite fashion. | ||
|
||
The next observation to be made is that, if a graph is bipartite there are 2 ways to color the graph. | ||
One is with the starting node as ruby and all its children as emerald and vice versa. | ||
|
||
The final observation is that, since the graph may have many connected components, the number of ways to color the graph will be 2 ^ (number of connected components) since all colorings of connected components are independent. | ||
|
||
So we need to check for the number of connected components and return 2 ^ (number of connected components). | ||
|
||
Thus the answer is, | ||
0 if the graph is not bipartite. | ||
else it is 2 ^ (number of connected components). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#include<bits/stdc++.h> | ||
using namespace std; | ||
|
||
bool dfs(vector<vector<int> >& graph, vector<int>& vis, int i, int c) { | ||
if(vis[i] == (c ^ 1)) return false; | ||
if(vis[i] != -1) return true; | ||
vis[i] = c; | ||
bool res = true; | ||
for(int x: graph[i]) res = res & dfs(graph, vis, x, c ^ 1); | ||
return res; | ||
} | ||
|
||
void checkBiPartite(vector<vector<int> >& graph, int n, bool& check, int& count) { | ||
vector<int> vis(n + 1, -1); | ||
for(int i = 1; i <= n; ++i) { | ||
if(vis[i] == -1) { | ||
check &= dfs(graph, vis, i, 1); | ||
++count; | ||
} | ||
} | ||
} | ||
|
||
int main() { | ||
int n; | ||
cin >> n; | ||
int f; | ||
cin >> f; | ||
vector<vector<int> > graph(n + 1, vector<int>()); | ||
for(int i = 0; i < f; ++i) { | ||
int x, y; | ||
cin >> x >> y; | ||
graph[x].push_back(y); | ||
graph[y].push_back(x); | ||
} | ||
|
||
bool check = true; | ||
int count = 0; | ||
|
||
checkBiPartite(graph, n, check, count); | ||
|
||
if(!check) cout << 0 << endl; | ||
else cout << int(pow(2, count)) << endl; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Tags: Hashmap, Sets | ||
|
||
Since the characters are independent of upper or lower case, we can make every character lower case (or upper case). | ||
|
||
The problem then requires you to check the occurence of all 26 characters, a set can be used to store all unique character. | ||
If the size of the set's 26, it implies that all characters occur in the string. | ||
|
||
Alternatively, a hashmap of sorts can be used to track the occurence of each character. The hashmap can then be traversed to | ||
verify 26 occurences. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#include<bits/stdc++.h> | ||
using namespace std; | ||
|
||
int main() { | ||
int n; | ||
cin >> n; | ||
string s; | ||
cin >> s; | ||
|
||
vector<bool> occur(26, false); | ||
for(char x: s) { | ||
if(x <= 'Z') occur[x - 'A'] = true; | ||
else occur[x - 'a'] = true; | ||
} | ||
|
||
int count = 0; | ||
for(bool x: occur) if(x) ++count; | ||
|
||
if(count == 26) cout << "YES\n"; | ||
else cout << "NO\n"; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
n = int(input()) | ||
s = input() | ||
s = s.lower() | ||
a = set() | ||
for c in s: | ||
if c not in a: | ||
a.add(c) | ||
if len(a) == 26: | ||
print("YES") | ||
else: | ||
print("NO") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
**Tags**: Sorting | ||
|
||
|
||
On visualizing the stacks, it can be seen that the crates fall to the right as long as there's no other crate | ||
preventing this right-ward movement. | ||
|
||
Following this visualization, the tallest stack will be the rightmost one, followed by the 2nd smallest one, in | ||
non-decreasing order. | ||
|
||
Hence, simply sorting the numbers would do the trick. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#include <bits/stdc++.h> | ||
using namespace std; | ||
using ll = long long; | ||
|
||
int main() | ||
{ | ||
cin.tie(0) -> sync_with_stdio(0); | ||
|
||
int tt; | ||
cin >> tt; | ||
while (tt--) { | ||
ll n; | ||
cin >> n; | ||
vector<ll> stacks(n); | ||
for(int i = 0; i < n; ++i) { | ||
cin >> stacks[i]; | ||
} | ||
|
||
sort(stacks.begin(), stacks.end()); | ||
|
||
for (ll i : stacks) { | ||
cout << i << " "; | ||
} | ||
cout << "\n"; | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
Tags: Dynamic Programming | ||
|
||
A valid subset contains points that have the following property: if we sort them increasingly by the x-coordinate, they will be sorted decreasingly by the y-coordinate. | ||
|
||
First we sort all points, this way it's guarranteed that the x coordinates are in ascending order, now for a given set of coordinates, we find the number of coordinates before it which have the y coordinate greater than equal to it. | ||
|
||
Hence, to count the total number of subsets, we can come up with the following dynamic programming solution: | ||
|
||
DP[i] = the number of valid subsets such that the point with the greatest x-coordinate is "i". | ||
We build DP[i] by iterating j along 0 to i - 1, such that DP[i] += DP[j] where j.x < i.x and j.y > i.y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#include <bits/stdc++.h> | ||
using namespace std; | ||
using ll = long long; | ||
|
||
const ll mod = 1e9 + 7; | ||
|
||
int main(void) { | ||
int n; | ||
cin >> n; | ||
|
||
auto updateTotal = [&](ll total, ll value) -> ll { | ||
// lambda function to update total | ||
return (total + value) % mod; | ||
}; | ||
|
||
vector<pair<int, int>> pointsSet; // Store all the points here | ||
for (int i = 0; i < n; i++) { | ||
int x, y; | ||
cin >> x >> y; | ||
pointsSet.push_back({x, y}); | ||
} | ||
sort(pointsSet.begin(), pointsSet.end()); // Sort points in ascending order | ||
vector<ll> dp(n); | ||
for (int i = 0; i < n; i++) { | ||
ll total = 1; | ||
for (int j = 0; j < i; j++) { | ||
if (pointsSet[j].second > pointsSet[i].second) { | ||
total = updateTotal(total, dp[j]); | ||
// Update total if it matches the required condition | ||
} | ||
} | ||
dp[i] = total; | ||
} | ||
ll ans = 0; | ||
for (int i = 0; i < n; i++) { | ||
ans = updateTotal(ans, dp[i]); | ||
// Find the sum of all the values in the dp array | ||
} | ||
cout << ans << endl; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
Tags: Binary Search | ||
|
||
To find the minimum number of students that need to be moved around, we need to find the maximum number | ||
of students that can stay in place. To do this, we must find the longest increasing subsequence (LIS). | ||
|
||
It should be noted that this could've been a dynamic programming problem if the constraints allowed it. | ||
|
||
Eg. | ||
2 4 1 5 3 6 7 | ||
|
||
The longest increasing sequence in this example is 2 4 5 6 7. | ||
Numbers that are left out are 1 and 3, these are the numbers that are needed to be rearranged. | ||
Now, all we have to do is find len(sequence) - len(LIST) to get our answer. | ||
|
||
Our goal is to find the longest increasing sequence. | ||
We'll start by initializing an array *LIS* to *height[0]* (First element of height). The length of this array will provide us the length of the longest sequence. | ||
|
||
1. Iterating through each element of the array height we check if element *height[i]* is greater than the last element of LIS. If it is, then the element is added to the end of LIS. | ||
(This step ensures that LIS is a sorted list and, an element that is larger than the last element of LIS will be part of the longest sequence) | ||
|
||
2. If the element is not larger then we'll have to find its position in LIS. | ||
This is done by finding the lower bound(The next smallest number just greater than or equal to the element) in LIS. | ||
This can be solved using binary search, or the in-build lower_bound() (C++) or bisect_left() (python) | ||
Let this lower bound index be **idx** | ||
LIS[idx] is updated to height[i]. | ||
|
||
At the end, the size of LIS corresponds to the length of the longest increasing subsequence, but it must be noted that the elements | ||
itself do not correspond to a valid longest increasing subsequence. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
def LowerBound(arr, x, l, h): | ||
if h >= l: | ||
mid = (h + l) // 2 | ||
if arr[mid] == x: | ||
return mid | ||
elif arr[mid] > x: | ||
return LowerBound(arr, x, l, mid - 1) | ||
elif(arr[mid] < x): | ||
return LowerBound(arr, x, mid + 1, h) | ||
else: | ||
return l | ||
|
||
|
||
t = int(input()) | ||
|
||
for _ in range(t): | ||
n = int(input()) | ||
height = list(map(int,input().split())) | ||
LIS = [height[0]] | ||
|
||
for i in range(1, n): | ||
if height[i] >= LIS[-1]: | ||
LIS += [height[i]] | ||
else: | ||
idx = LowerBound(LIS, height[i], 0, len(LIS) - 1) | ||
LIS[idx]=height[i] | ||
print(n - len(LIS)) |
Oops, something went wrong.