Thanks everybody for participating in the round!
A. Shortest Increasing Path
How big can the answer be?
Which coordinates can you reach in $$$2$$$ or $$$3$$$ moves?
This problem is about handling cases.
The main solution is to quickly realize that $$$x \lt y$$$ can be done in 2 moves and $$$x \gt y+1$$$ with $$$y \gt 1$$$ in 3. You can guess that other cases are impossible.
Using two moves, we can move to any ($$$x$$$,$$$y$$$) with $$$x \lt y$$$ by first moving $$$x$$$ and then $$$y$$$. Using 3 moves $$$0 \lt a \lt b \lt c$$$ we get to ($$$a+c$$$,$$$b$$$) as follows: first to ($$$a$$$,$$$0$$$), then to ($$$a$$$, $$$b$$$), and then to ( $$$a+c$$$, $$$b$$$). Without loss of generality we can subtract $$$1$$$ from $$$a$$$ and add $$$1$$$ to $$$c$$$ anytime so we can assume $$$a=1$$$ and hence we can reach ($$$x$$$, $$$y$$$) in $$$3$$$ moves if and only if $$$x \gt y+1$$$ and $$$y \gt 1$$$.
Now assume we can reach some ($$$x$$$, $$$y$$$) with $$$k \gt 3$$$ jumps. The last two jumps can be merged with the previous 2 jumps giving a solution with $$$k-2$$$ jumps. Hence any other case is impossible.
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
#define int long long
signed main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int t;
cin>>t;
while(t--){
int x,y;
cin>>x>>y;
if(x==y || x==y+1 || y==1)cout<<-1<<endl;
else if(x<y)cout<<2<<endl;
else cout<<3<<endl;
}
}
B. Multiple Construction
Don't over complicate, there is a simple construction
There is a construction where each number $$$x$$$ is placed at distance either $$$x$$$ or $$$2 \cdot x$$$.
here is a construction where only the number $$$n$$$ is placed at distance $$$n$$$. All other numbers are placed at distance $$$2 \cdot x$$$.
There is a construction where the first element of the array is always $$$n$$$.
There are multiple ways to solve this problem. We believe the easiest one is based on the following construction:
$[ n, n-1, n-2, \ldots, 3, 2, 1, n, 1, 2, 3, \ldots, n-2, n-1 ]$
It's easy to see that both occurrences of $$$n$$$ are at a distance of $$$n$$$, and all the other values appear at a distance of twice their value. In other words, we place the two $$$n$$$'s at the first position and at the $$$(n+1)$$$-th position, then we use the second $$$n$$$ as a pivot to place numbers from $$$1$$$ to $$$n-1$$$ in order.
There exist other constructions as well. For example, for $$$n$$$ odd, we can use:
$[ 1, n-2, n-4, \ldots, 3, n, 1, 3, 5, \ldots, n-2, n-1, n-3, \ldots, 2, n, 2, \ldots, n-3, n-1 ] $ For $$$n$$$ even, the pattern is similar but we adjust the positions of $$$n-1$$$ and $$$n-2$$$ accordingly.
A greedy algorithm also works: we go from $$$n$$$ to $$$1$$$, and try to place each number in the leftmost possible position. Note that this greedy algorithm follows the same pattern as the first construction.
#include <bits/stdc++.h>
using namespace std;
int t, n;
signed main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
cin >> t;
while (t--) {
cin >> n;
for (int i = n; i >= 1; i--) {
cout << i << " ";
}
cout << n;
for (int i = 1; i < n; i++) {
cout << " " << i;
}
cout << "\n";
}
}



