题目:1-400号运动员排成一排,下令所有单号的运动员出列离开,剩下的重新排号再下令单号的出列离开,重复直到剩下一人为止,这个人在最初的400人中排多少号?
/**
* @author zql
*/
public class RemoveOdd {
public static void main(String[] args) {
int[] s = new int[400];
for (int i = 0; i < 400; i++) {
s[i] = i + 1;
}
int r = recursive(s);
System.out.println("这个人在最初的400人中排" + r + "号");
int n = 400;
System.err.println("这个人在最初的" + n + "人中排" + getResult(n) + "号");
}
/**
* 递归实现
*
* @param arr 装有原号码的数组
* @return
*/
public static int recursive(int[] arr) {
// 定义一个新的数组,用于装剩下的双号
int[] newInts = new int[arr.length / 2];
// 定义索引
int index = 0;
// 号码从1开始
for (int i = 1, len = arr.length; i <= len; i++) {
// 不是单号不存入新数组
if (i % 2 == 0) {
newInts[index++] = arr[i - 1];
}
}
// 剩余一人时返回
if (newInts.length == 1) {
return newInts[0];
}
return recursive(newInts);
}
/**
* 循环实现
*
* @param maxNo 最大的号码
* @return
*/
public static int getResult(int maxNo) {
int[] no = new int[maxNo];
for (int i = 0; i < maxNo; i++) {
no[i] = i + 1;
}
// 结果
int r = -1;
// 声明一个新的数组,,用于装剩下的双号
int[] newInts = null;
// 定义长度并赋值
int len = no.length;
boolean bl = true;
while (bl) {
int index = 0;
// 实例化装双号的数组,长度为号码数组的一半
newInts = new int[len/2];
// 号码从1开始
for (int i = 1; i <= len; i++) {
// 不是单号不存入新数组
if ( i % 2 == 0) {
newInts[index++] = no[i - 1];
}
}
len = newInts.length;
// 剩余一人时结束while循环,并把结果赋给r
if (newInts.length == 1) {
r = newInts[0];
bl = false;
}
// 重新排列号码
no = new int[len];
for (int i = 0;i < len; i++) {
no[i] = newInts[i];
}
}
return r;
}
}