关键是对删除后的剩余情况重新编号,再看新编号怎么映射回原先编号。
约瑟夫环问题
0 ~ i-1的i个数字排成环,每次数到m删一个数字,最后剩下哪个数?
第一次删除数字(m-1)%i,删除数字后开始重新编号0 ~ i-2,比如被删除数后面的数((m-1)+1)%i = m%i =重编号=> 0。反过来,0=映射回=> m%i,从删除后=映射回=>删除前 p(x)=(x+m)%i,i是删除前的个数。从最终只剩x=0逆推。
int ysf(int n, int m) {
// 例如,(1+m) % len => 1,反过来就是 1 => (1+m) % len
// 推广到 x => (x+m) % len
int x = 0; // 涉及到模运算,从0开始
for (int i = 2; i <= n; i++) {
x = (x + m) % i;
}
return x + 1; // 从1开始编号
}