W zeszłym tygodniu uczestniczyłem w rundzie 1b na Facebooku Hackers Cup.Flawiusz za duże n (Facebook Hacker Cup)
Jednym z problemów było w zasadzie Josephus problem
Uczyłem problem Józef wcześniej jako dyskretny problem matematyczny, więc ja po prostu zrozumieć, jak uzyskać nawrotom:
f(n,k) = (f(n-1,k) + k) mod n, with f(1,k) = 0
ale nie zrobił pracują w Puchar Hackera Facebooka, ponieważ maksymalna wartość n wynosi 10^12. Wartość mak k wynosi 10^4.
Wikipedia wspomina o podejściu, gdy k jest małe, a n jest duże. Zasadniczo usuń ludzi z jednej rundy, a następnie ponumeruj. Ale to nie jest opisane wiele i nie rozumiem, dlaczego numeracja działa.
Sprawdziłem przykładowy kod źródłowy rozwiązania, ale nadal nie rozumiem tej ostatniej części.
long long joseph (long long n,long long k) {
if (n==1LL) return 0LL;
if (k==1LL) return n-1LL;
if (k>n) return (joseph(n-1LL,k)+k)%n;
long long cnt=n/k;
long long res=joseph(n-cnt,k);
res-=n%k;
if (res<0LL) res+=n;
else res+=res/(k-1LL);
return res;
}
Część I naprawdę nie rozumiem, począwszy od res-=n%k
(a linie później). Jak wywnioskować, że jest to sposób na dostosowanie wyniku?
Czy ktoś może przedstawić uzasadnienie tego, w jaki sposób się wywodzi? Lub link, który go wyprowadza? (Nie znalazłem żadnych informacji na temat forów UVA lub topcoder)
Które "jeśli" należy do ostatniego "innego"? – biziclop
@biziclop - czy nie jest to raczej oczywiste, że należy do ostatniego ...? – IVlad
@IVlad: Czy nie jest dla ciebie oczywiste, że jeśli pytanie ma być zadane, kodeks cierpi na brak jasności? – JimR