問題
コード
Javaで解いてみました。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int nN = sc.nextInt();
int nM = sc.nextInt();
// nM 番目の名刺が何枚目のファイルにあるか?
int nK = (nM + (2 * nN - 1)) / (2 * nN);
// nK 枚目のファイルの名刺番号の表、裏を足すと
// 一定の値になることから。
// mK番目のファイルにある、1枚目と2n枚目の
// 番号を足す。
int nS // = (2 * nN * (nK - 1) + 1) + (2 * nN * nK)
= 4 * nN * nK - 2 * nN + 1;
// nM番目の名刺の裏にある名刺番号を求める。
int nR = nS - nM;
System.out.println(nR);
}
}
解説
標準入力からの数値の読み取り
Scanner インスタンスを作り、nextInt()メソッドで数値を取得しています。
- ファイルの1面に入る名刺の数:$n$
- 求める名刺番号の表側の番号:$m$
m 番目の名刺が、何ファイル目に格納されているかを求める。
求める値$k$は、$m$ を$2n$ で割、余りがあったら切り上げます。
つまり、$m$ に $2n-1$ を足して、$2n$で整数除算すれば良いので、
k = \frac{m + (2n - 1)}{2n} (整数除算)
となります。
k ファイル目の名刺番号(表と裏)の法則
$k$ ファイル目の名刺番号について、表と裏(あるいは、裏と表)を足すと一定の値になっていることに気づきます。
- $k$ ファイル目の$1$番目の名刺番号:$2n(k - 1) + 1$
- $k$ ファイル目の$2n$番目の名刺番号:$2nk$
つまり、$k$ ファイル目の表と裏の名刺番号を足した値$s$は、
s = (2n(k - 1) + 1) + 2nk = 4nk - 2n + 1
求める名刺番号
$s$ から $m$ を引けば、$m$の裏の名刺の番号になる。
$$ r = s - m $$