约瑟夫问题
\(n\) 个人编号 \(0,1,2…,n-1\) ,每次数到 \(k\) 出局,求最后剩下的人的编号。
\(\mathcal O(N)\) 。
int jos(int n,int k){int res=0;repeat(i,1,n+1)res=(res+k)%i;return res; // res+1,如果编号从1开始
}
\(\mathcal O(K\log N)\) ,适用于 \(K\) 较小的情况。
int jos(int n,int k){if(n==1 || k==1)return n-1;if(k>n)return (jos(n-1,k)+k)%n; // 线性算法int res=jos(n-n/k,k)-n%k;if(res<0)res+=n; // mod nelse res+=res/(k-1); // 还原位置return res; // res+1,如果编号从1开始
}
