Información del tema
Hay n personas en un círculo, dispuestas en orden. Empiece a contar desde la primera persona (de 1 a 3). Cualquiera que informe a 3 se retirará del círculo y preguntará cuál es el número original que queda al final.
respuesta
Este tema es relativamente clásico y también se conoce como el problema del anillo de Joseph. Los amigos que estén interesados pueden buscar el anillo de Joseph.
Haga un ejemplo simple, tome a 10 personas para informar el número y luego salga
En el ejemplo anterior, puede ver:
- Defina la matriz inicial, el valor inicial de la posición de la matriz es 0
- El contador solo informa el número donde el valor es 0
- Cuando el contador informe a 3, modifique el valor de posición a 1 y el número restante de personas se reducirá en 1
- Anuncie el número en un bucle, salga cuando el número restante sea 1
- Cuando la matriz se repite hasta el final, la posición de la matriz se establece en 0
- Si el valor de la posición en bucle no es 0, la posición se moverá después de agregar 1
- Cuando el ciclo salga, imprima la matriz y muestre la posición de 0
codificación
Implementación de matrices
De acuerdo con el análisis del problema anterior, use la matriz para realizar el algoritmo
/**
* 报数退出
* @param m 总人数
* @param n 报到n时退出
*/
public static void reportNumber(int m, int n) {
// 初始化数组长度为m,初始化报数器speaker为0
int[] arr = new int[m];
int speaker = 0;
// 初始化剩余人数left为m,数组元素位置arrLocation为0
int left = m;
int arrLocation = 0;
// 循环数组,报数,剩余人数为1时退出
while (left > 1) {
if (arr[arrLocation] == 0) {
// 数组位置为0时,报数
speaker++;
// 报到n时,报数器speaker置0
// 数组位置值修改为1,剩余人数left减1
if (speaker == n) {
speaker = 0;
arr[arrLocation] = 1;
left--;
}
// 完成当次报数后,位置加1
// 若数组位置值为数组长度时,说明到了数组末尾,将位置置0,开启新一轮的循环
arrLocation++;
if (arrLocation == m) {
arrLocation = 0;
}
} else {
// 数组位置不为0时,直接移动位置;
// 若数组位置值为数组长度时,说明到了数组末尾,将位置置0,开启新一轮的循环
arrLocation++;
if (arrLocation == m) {
arrLocation = 0;
}
}
}
for (int i=0; i<arr.length; i++) {
if (arr[i] == 0) {
System.out.println(i+1);
}
}
}
La implementación anterior es la última persona restante. Si el tema se modifica ligeramente, la 1 persona restante se modifica para que sea menor que n, y luego left> 1 en la condición while se modifica a left> n.
implementación de lista
La implementación de la lista es similar a la de la matriz, pero ligeramente diferente, como sigue
/**
* 报数退出
* @param m 总人数
* @param n 报到n时退出
*/
public static void reportNumberList(int m, int n) {
// 初始化list,list置每个位置初始值
List<Integer> list = new ArrayList<>();
for (int i=0; i<m; i++) {
list.add(i+1);
}
// 初始化报数器speaker为0
int speaker = 0;
// 初始化list元素位置arrLocation为0
int arrLocation = 0;
// 循环list,报数,剩余1个人时退出
while (list.size() > 1) {
// 报数
// 同数组实现不同,list中将报到为n的位置直接删除了
speaker++;
// 报到n时,报数器speaker置0
// 删除list该位置的元素
if (speaker == n) {
speaker = 0;
list.remove(arrLocation);
// 若数组位置值为list长度,说明到了list末尾,将位置置0,开启一次新的循环
if (arrLocation == list.size()) {
arrLocation = 0;
}
} else {
// 完成当次报数后,位置加1
// 若数组位置值为list长度,说明到了list末尾,将位置置0,开启一次新的循环
arrLocation++;
if (arrLocation == list.size()) {
arrLocation = 0;
}
}
}
System.out.println(list.get(0));
}
Prueba de código
public static void main(String[] args) {
reportNumber(10, 3);
reportNumberList(10, 3);
reportNumber(100, 3);
reportNumberList(100, 3);
}
4
4
91
91
La prueba encontró que cuando hay 10 personas, la posición de la última persona restante es 4, que es lo mismo que el análisis del problema; cuando hay 100 personas, la posición de la última persona restante es 91