This is the editorial for the Unofficial Div 4 Round #2 created by SlavicG and mesanu.
We hope everyone had fun and enjoyed the contest!
We apologize for the queue at the beginning of the round. We should have used multi tests to avoid this problem.
Problem A — Catching the Impostor.
The problem is just implementation. Check if exactly $$$n-1$$$ numbers are encountered. You can easily do this using a set or a frequency array.
#include "bits/stdc++.h"
using namespace std;
int main()
{
set<int> s;
int n, m;
cin >> n >> m;
for(int i = 0;i < m;i++){
int x;
cin >> x;
s.insert(x);
}
if(s.size() == n - 1){
cout << "YES";
}else{
cout << "NO";
}
}
Problem B — Rabbit Game
We iterate from the start and see how many carrots the first rabbit can eat, let this be $$$cnt_1$$$. We iterate from the end to see how many carrots the second rabbit can eat, let this be $$$cnt_2$$$. If $$$cnt_1 + cnt_2 > n$$$ then some carrots will be eaten by both rabbits, but this is not possible because they stop whenever they meet. The answer is $$$min(n, cnt_1+cnt_2)$$$.
//Solution for B will be available soon
Problem C — Similar Arrays
The array we make should consist only of the median of the array (the middle element after sorting the array). If $$$n$$$ is even and there are two medians, both medians and all values between them are optimal choices.
The median is an optimal choice because if $$$x$$$ (any element from the array) is smaller than the median, the sum becomes smaller by increasing $$$x$$$, and if $$$x$$$ is larger than the median, the sum becomes smaller by decreasing $$$x$$$. Hence, the optimal solution is that $$$x$$$ is the median.
#include "bits/stdc++.h"
using namespace std;
int main()
{
int n;
cin >> n;
int a[n];
for(int i = 0;i < n;i++){
cin >> a[i];
}
sort(a,a+n);
long long ans = 0;
int median = a[n/2];
for(int i = 0;i < n;i++){
ans += abs(median - a[i]);
}
cout << ans;
}
Problem D — Sanda's Job
We need to find if the difference between $$$n$$$ and $$$x$$$ is also a permutation of $$$x$$$'s digits. There are many ways to do this, and our solution is to transform $$$x$$$ and $$$n-x$$$ into strings, then sort the strings and see if they are equal. This is possible in C++ using to_string(int value) function.
#include "bits/stdc++.h"
using namespace std;
int main()
{
long long n,m;
cin >> n >> m;
m-=n;
if(m <= 0){
cout << "NO";
return 0;
}
string s = to_string(n);
string k = to_string(m);
sort(s.begin(), s.end());
sort(k.begin(), k.end());
if(k==s){
cout << "YES\n";
}else{
cout << "NO\n";
}
}
Problem E — Count Substrings
We iterate through string $$$s$$$, and whenever we encounter a substring $$$t$$$, we add to the answer the number of unique substrings we can make using it. We can calculate this with the formula (number of characters since the start of the last encounter)$$$\cdot$$$(the number of characters until the end of the string). This is because the start of the substring must be between the start of the last $$$t$$$ substring in $$$s$$$ and the start of the $$$t$$$ substring just encountered(so we don't double count previous substrings). The end must be between the last element of this $$$t$$$ substring and the last element of string $$$s$$$.
#include "bits/stdc++.h"
using namespace std;
int main()
{
string s, t;
long long n;
cin >> n >> s >> t;
long long l = 0;
long long ans = 0;
for(int i = 0; i < n-1; i++)
{
if(s[i] == t[0] && s[i+1] == t[1])
{
long long from = i-l+1;
long long to = n-(i+1);
ans += from*to;
l = i + 1;
}
}
cout << ans << endl;
}
Problem F — Game on Grid
we can find the answer by looking at the cases depending on n % 4, or we can use a formula. In either case, below is proof of why it works.
Let's solve this problem for a more general case of rectangular grid $$$n \times m$$$, with rows and columns counted starting from $$$1$$$. Let even cell denote a cell with both even coordinates, all shown on the right drawing.
Consider $$$X = \left \lfloor{ \frac{n}{2} }\right \rfloor \cdot \left \lfloor{ \frac{m}{2} }\right \rfloor$$$ squares with even bottom-right corners, as shown on the left drawing. Since the squares are disjoint and Bob colors only one cell per move, he can block Alice from at most one of those $$$X$$$ squares per turn. Alice starts so she can color $$$\left \lceil{ \frac{X}{2} }\right \rceil$$$ of the $$$X$$$ squares and thus guarantee the score of $$$4 \cdot \left \lceil{ \frac{X}{2} }\right \rceil$$$, no matter what Bob does.
There are $$$X$$$, even cells. Alice covers exactly one of them per move because any possible $$$2 \times 2$$$ square contains exactly one even cell. If Bob colours an even cell every time too, they will spend $$$X$$$ moves in total to block all even cells, and then Alice won't be able to move. This way Bob can guarantee that Alice makes at most $$$\left \lceil{ \frac{X}{2} }\right \rceil$$$ moves and gets the score of $$$4 \cdot \left \lceil{ \frac{X}{2} }\right \rceil$$$.
Alice can make her score to be at least $$$4 \cdot \left \lceil{ \frac{X}{2} }\right \rceil$$$ and Bob can make Alice's score to be at most $$$4 \cdot \left \lceil{ \frac{X}{2} }\right \rceil$$$. Her score is thus exactly:
Bob's score must be $$$B = n \cdot m - A$$$ because he can always finish the whole grid. We can compare $$$A$$$ with $$$B$$$ to get the answer.
Alternatively, you can consider cases depending on $$$n \bmod 4$$$ and $$$m \bmod 4$$$. For example, if $$$n = m = 4 \cdot k + 1$$$ then $$$X = 2k \cdot 2k = 4 \cdot k^2$$$ so $$$A = 4 \cdot (2 \cdot k^2) = 8 \cdot k^2$$$. That's smaller than half of full grid area $$$(4 \cdot k + 1)^2$$$ so Bob wins.
(We don't claim anything about the optimal moves of Alice and Bob. In particular, Alice doesn't have to choose exactly those squares marked on the drawing.)
#include "bits/stdc++.h"
using namespace std;
int main()
{
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
if(n%4==2){
cout << "Alice\n";
}else if(n%2==0){
cout << "Draw\n";
}else{
cout << "Bob\n";
}
}
}
#include "bits/stdc++.h"
using namespace std;
int main()
{
long long n;
cin >> n;
long long cover = ((n / 2) * (n / 2) + 1) / 2;
long long as = 4 * cover;
long long bs = n * n - as;
if (as == bs) cout << "Draw\n";
else if (as < bs) cout << "Bob\n";
else cout << "Alice\n";
}