考慮這樣一個(gè)問(wèn)題,有 個(gè)人,標(biāo)號(hào)從
到
,從第一個(gè)人開(kāi)始數(shù),殺死數(shù)到
的人,然后下一個(gè)人重新開(kāi)始數(shù)。
問(wèn):最后死的人是幾號(hào)?
假設(shè)有 個(gè)人,將沒(méi)有被殺的人重新編號(hào),那么,殺人情況如下表所示
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|
| 11 | 12 | 13 | 14 | 15 | 16 | 17 | |||
| 18 | 19 | 20 | 21 | 22 | |||||
| 23 | 24 | 25 | |||||||
| 26 | 27 | ||||||||
| 28 | |||||||||
| 29 | |||||||||
| 30 |
第一輪殺了 號(hào)、
號(hào)和
號(hào),
號(hào)變成了
號(hào),
號(hào)變成了
號(hào)等等。
我們可以發(fā)現(xiàn)如下性質(zhì):
- 每一輪被殺的了人的編號(hào)是
的倍數(shù),且第
個(gè)被我要的殺的人的當(dāng)前輪的編號(hào)是
。
-
號(hào)被殺后,下一個(gè)被殺的人是
號(hào),那么
號(hào)和
號(hào)是暫時(shí)安全的,因此需要對(duì)其編號(hào),其新的編號(hào)為
和
,因?yàn)闅⑼?
號(hào)后相當(dāng)于殺了
個(gè)人,還有
個(gè)人。
因此對(duì)于第 個(gè)被殺死的人,他死亡時(shí)編號(hào)為
,又因?yàn)?
或
,顯然
,而上一輪的編號(hào)為
。
因此可以用下面的方法算出最后一個(gè)死的人的原編號(hào)
int J(int n) {
int i = 3 * n;
while (i > n) i = (i - n - 1) / 2 + i - n;
return i;
}
如果用 來(lái)替換
,發(fā)現(xiàn)原迭代式變?yōu)?
則可以用以下方法求出上面要求的結(jié)果
int J(int n) {
int i = 1;
while (i <= 2*n) i = ceil(3.0 * i / 2);
return 3*n + 1 - i;
}
當(dāng)然,如果循環(huán)節(jié)的個(gè)數(shù)不為 ,而是為
,可以用相同的方法證明,有類似的結(jié)論
int J(int n, int q) {
int i = 1;
while (i <= (q - 1) * n) d = ceil((double)q * i / (q - 1));
return q*n + 1 - i;
}