需求
目前有100名囚犯,每个囚犯的编号是1-200之间的随机数。现在要求依次随机生成100名囚犯的编号(要求这些囚犯的编号是不能重复的),然后让他们依次站成一排。(注:位置是从1开始计数的),接下来,国王命令手下先干掉全部奇数位置处的人。剩下的人,又从新按位置1开始,再次干掉全部奇数位置处的人,依此类推,直到最后剩下一个人为止,剩下的这个人为幸存者。
具体功能点的要求如下:
请输出幸存者的编号,以及他第一次所占的位置值是多少。
定义囚犯对象
package day01_the_first;
//囚犯对象
public class People {
private int code; //编号
private int location; //位置
public People() {
}
public People(int code, int location) {
this.code = code;
this.location = location;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public int getLocation() {
return location;
}
public void setLocation(int location) {
this.location = location;
}
@Override
public String toString() {
return "People{" +
"code=" + code +
", location=" + location +
'}';
}
}
解决问题
package day01_the_first;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* 从对象层面来解决囚徒存活问题
*/
public class Test2 {
//完成幸存者案例
//1、由于每个囚犯可以当作是一个对象,并且我们需要每个囚犯的编号和位置,所以这道题使用对象来做更好
//2、创建100个囚犯,依次占位,并为其赋编号(1-200之间的随机数,不能重复)
public static List<People> peoples = new ArrayList<>(); //使用多态写法 静态
public static void main(String[] args) {
//3、循环100次创建100个囚犯对象,存入集合
Random r = new Random();
for (int i = 1; i <= 100; i++) {
int code = r.nextInt(200) + 1;
if (judge(code)) {
People p = new People(code, i);
peoples.add(p); //当前囚犯添加成功
} else {
i--;
}
}
System.out.println("囚犯占位:" + peoples);
//4、反复删除奇数位置的人,直到剩余一个人
while (peoples.size() > 1) {
//干掉奇数位置的人剩下的就是留下偶数位置的人
List<People> people1 = new ArrayList<>();
for (int i = 0; i < peoples.size(); i++) {
if (i % 2 == 1) {
people1.add(peoples.get(i));
}
}
System.out.println(people1);
peoples = people1; //让临时集合替换上面的peoples,使得循环继续执行
}
People uniPeople = peoples.get(0);
System.out.println(uniPeople);
}
//判断是否编号已经存在
public static boolean judge(int code){
for (People people : peoples) {
if(people.getCode() == code){
return false; //重复
}
}
return true; //没有与之重复的
}
}
可以看到使用对象来完成囚犯存活问题是一种更好的解法,我们以后面对问题时,也应该要先想是不是可以从对象层面去解决这个问题。