D - Hands on Ring (Easy) 解説 by en_translator
Scan the \(Q\) instructions in order, while managing the current positions of your left and right hand, and the minimum number of operations required so far. Managing the positions is straightforward; the main part is to implement a program that responds to the following type of query:
- You are given integers \(\mathrm{from},\mathrm{to}\), and \(\mathrm{ng}\), each between \(1\) and \(N\). How many steps are required one you need to walk on the cycle from part \(\mathrm{from}\) to part \(\mathrm{to}\) without passing through part \(\mathrm{ng}\)? (It is guaranteed that \(\mathrm{from}\neq\mathrm{ng}\) and \(\mathrm{to}\neq\mathrm{ng}\).)
This can be solved by doing casework depending on the ordering of \(\mathrm{from},\mathrm{to}\), and \(\mathrm{ng}\). There are six possible orderings for three integers, so one may consider each of them; but it can be reduced to two by considering as follows, which simplifies implementation.
First, note that we may swap \(\mathrm{from}\) and \(\mathrm{to}\) freely (the number of steps required to travel from \(\mathrm{from}\) to \(\mathrm{to}\) is equal to that from \(\mathrm{to}\) to \(\mathrm{from}\)). This allows us to swap \(\mathrm{from}\) and \(\mathrm{to}\) if \(\mathrm{from}>\mathrm{to}\), so that we always have \(\mathrm{from}\leq \mathrm{to}\). (The technique like this of reducing casework by fixing the ordering is often effective.)
All that left is the position of \(\mathrm{ng}\), but there are essentially two cases: \(\mathrm{from}<\mathrm{ng}<\mathrm{to}\), and otherwise.
For the former, it is optimal to move as \(\mathrm{from}\rightarrow\mathrm{(from-1)}\rightarrow\dots\rightarrow 1 \rightarrow N\rightarrow \dots\rightarrow \mathrm{(to+1)}\rightarrow\mathrm{to}\), requiring \((\mathrm{from}-1)+1+(N-\mathrm{to})=N+\mathrm{from}-\mathrm{to}\) steps.
For the latter, it is optimal to move as \(\mathrm{from}\rightarrow\mathrm{(from+1)}\rightarrow\dots\rightarrow \mathrm{(to-1)}\rightarrow\mathrm{to}\), requiring \(\mathrm{to}-\mathrm{from}\) steps.
By implementing this, the problem can be solved in a total of \(O(N)\) time.
Sample code (C++):
#include <bits/stdc++.h>
using namespace std;
int num_move(int n, int from, int to, int ng) {
if (from > to) swap(from, to);
if (from < ng and ng < to) {
return n + from - to;
} else {
return to - from;
}
}
int main() {
int n, q;
cin >> n >> q;
int l = 1, r = 2;
int ans = 0;
for (int i = 0; i < q; i++) {
char h;
int t;
cin >> h >> t;
if (h == 'L') {
ans += num_move(n, l, t, r);
l = t;
} else {
ans += num_move(n, r, t, l);
r = t;
}
}
cout << ans << endl;
}
Sample code (Python) :
def num_move(n, from_, to, ng):
if from_ > to:
from_, to = to, from_
if from_ < ng < to:
return n + from_ - to
else:
return to - from_
n, q = map(int, input().split())
l, r = 1, 2
ans = 0
for _ in range(q):
h, t = input().split()
t = int(t)
if h == 'L':
ans += num_move(n, l, t, r)
l = t
else:
ans += num_move(n, r, t, l)
r = t
print(ans)
投稿日時:
最終更新: