问题A:
约瑟夫环问题:
0~n-1组成一个环,每次删除顺时针第m个元素,最后剩下哪个?
每轮删除后,新坐标->原坐标映射关系为,(i+m)%(n + 1)
通过最后一次坐标不断反求之前坐标。
注:1~n组成环,则映射为,(i+m-1)%n + 1
问题B:
一行代码求最大公约数:
不需要关心m,n谁大,两种方法都会在第一次执行交换过来。
需要满足的是,m和n必须非零。
方法1:
int gcd(int m,int n){
return n == 0? m : gcd(n, m%n)
}
方法2:
int gcd(int a, int b){
while(b^=a^=b^=a%=b);
return a;
}
问题C:
有关阶乘的问题:
给定一个N,返回N!结果末尾0的数量。
方法1:
统计因子5的数量。
方法2:
数学思维:
N!中因子5的个数有如下规律:
K = N/5 + N/(5^2) + N/(5 ^3) + … 直到5 ^ i > N
问题D:
给定一个N,返回N!二进制结尾0的数量。
统计因子2的数量K,有如下规律:
K = N - M
M为N二进制表达式中1元素的个数。