Day 26 | Upsolving Codeforces Div3 Round 820 (D|E) | C++
- Ayush Mahajan
- Sep 13, 2022
- 4 min read

Yesterday we solved Div3 A, B, and C. Today we are going to upsolve problems D and E.
The first question you should ask is if I couldn't solve D and E yesterday, how I solve them today? It is simple, I learned how to solve them. Yes, we keep learning what we don't know and ultimately we will have a good set of knowledge to perform better in contests. Of course, you need to give contests regularly as well because there are things like experience in contests that also affect your personal performance, but mainly it's practice.
Let's get started then
Friends and the Restaurant | C++ Solution
Let's see this is asking for maximizing the number of days we go to the restaurant, so if we go by how I try to solve it
We need to first decide on the approach we are going to use, and as per my binary search article I would try this way
Binary Search - It is the first thing I try to apply to a problem with words given above
Dynamic Programming - According to my experience it is the second thing I use
Greedy Approach
Mathematics
I tried the first 2 and no simple method struck my mind to solve by these 2 so I went with greedy. Another reason, which you might be able to understand better later in your journey, the problem seemed like a greedy problem.
Now, the problem asks us to sort into groups such that the expenditure is strictly less than or equal to the money they have.
So, let's keep an array of differences in expenditure and money they have so we can know how much extra money each person has. I have a plan to keep them sorted in the future, so using a multiset (as there can be repeated values as well)
We can do it like this -
multiset<int> extra;
for(int i = 0; i < n; i++)
extra.insert(money[i] - expenditure[i]);Now, we can find solutions like this
Take maximum and minimum from set
If their sum is >= 0, then make this a pair
Otherwise, remove the minimum and reconsider maximum
We can implement it like this
void solve(){
int n;
cin >> n;
vector<int> x(n), y(n);
for(int& i: x)cin >> i;
for(int& i: y)cin >> i;
multiset<int> s;
for(int i = 0; i < n; i++){
s.insert(y[i] - x[i]);
}
int ans = 0;
while(s.size() >= 2){
auto it = s.begin();
int lowest = *it;
s.erase(it);
it = prev(s.end());
int highest = *it;
if(lowest + highest < 0)continue;
s.erase(it);
ans++;
}
cout << ans << '\n';
}
But what is the proof that this will work?
Consider that we maximum and minimum do not give a positive result, then maybe the second maximum, maximum, and minimum give a positive result. But if we are making pairs that way, we don't need a minimum. If we remove the minimum, we will still find a valid pair (if nothing else is found) of maximum and second maximum
Interactive Problems
This is an interactive problem. If you have never attempted any interactive problems or have no idea what these are then go ahead and read this blog on the Codeforces on interactive problem
You can also get up to speed by solving this interactive problem
This sample problem is similar to binary search, where instead of calculating if mid is less than the answer we take input to get it.
We can implement it like this
int main(){
int lo = 1, hi = 1e6, ans;
while(lo <= hi){
int mid = (lo + hi) / 2;
cout << mid << endl;
string x;
cin >> x;
if(x == ">="){
//This mean answer is greater than or equal to mid
ans = mid;
lo = mid + 1;
}else{
//This means answer is less than mid
hi = mid - 1;
}
}
cout << "! " << ans << endl;
}Remember to flush your output. In C++, if you use endl to output a new line, then it flushes out the output buffer.
Guess the cycle size | C++ Implementation
In this problem, we can look at the following observation
There is a 50% chance of choosing either path
(? a b) and (? b a) can give different results
So if we keep asking like
(? 1 2) (? 2 1)
(? 1 3) (? 3 1)
(? 1 4) (? 4 1)
(? 1 5) (? 5 1)
and so on till 25 (max questions are 50)
Then given that path in both of them is chosen at a 50% chance, there is a very very high probability that we can get a smaller and greater path between two nodes at least once.
So we can try this way and print the sum when we get two different lengths for two queries
You can implement it like this
long long print_ques(long long a, long long b){
cout << "? " << a << " " << b << endl;
long long x;
cin >> x;
return x;
}
void print_ans(long long val){
cout << "! " << val << endl;
exit(0);
}
int main(){
long long a,b,ans;
for(int i = 2; i <= 26; i++){
long long x1 = print_ques(1,i);
long long x2 = print_ques(i,1);
if(x1 == -1){
print_ans(i-1);
}
if(x1 != x2){
print_ans(x1 + x2);
}
}
}Please like and share my posts if they are helpful.
![Day 44 | Binary Search Practice [Leetcode] | C++](https://static.wixstatic.com/media/fbea2a_167f1b66234f4d30b91bcf5b517f83f3~mv2.jpg/v1/fill/w_980,h_490,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/fbea2a_167f1b66234f4d30b91bcf5b517f83f3~mv2.jpg)
![Day 43 | Graph and Tree Practice [Leetcode] II | C++](https://static.wixstatic.com/media/fbea2a_361d6f7cd90c431b9f25518e1503da94~mv2.jpg/v1/fill/w_980,h_490,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/fbea2a_361d6f7cd90c431b9f25518e1503da94~mv2.jpg)
![Day 42 | Graph Practice [LeetCode] | C++](https://static.wixstatic.com/media/fbea2a_6570bb28577149f19db06704d542789a~mv2.jpg/v1/fill/w_980,h_490,al_c,q_85,usm_0.66_1.00_0.01,enc_avif,quality_auto/fbea2a_6570bb28577149f19db06704d542789a~mv2.jpg)
Comments