一、数3退1游戏解法
1)面向过程的解法
/**
* 数3退1测试 类
* @author fuchs
*
*/
public class TestCount3Quit {
public static void main(String[] args) {
/* 创建一个500个长度的布尔数组,表示500个小孩的状态 */
boolean[] kid = new boolean[500];
/* 将该布尔数组中的所有元素初始化为true,即所有小孩都在圈子中 */
for(int i=0; i<kid.length; i++) {
kid[i] = true;
}
/* 记录剩下的人数 */
int leftNum = kid.length;
/* 记录报的数字(1~3) */
int countNum = 0;
/* 记录数组下标(0~499),轮到第index个小孩 */
int index = 0;
/* */
/* 当人数大于1时,一直循环 */
while(leftNum > 1) {
if(kid[index] == true) {
countNum++; //报数
/* 报到3 */
if(countNum == 3) {
countNum = 0; //清零,下次从1开始数
kid[index] = false; //标记当前小孩为false,退出圈子
leftNum--; //剩下的人数自减
}
}
index++; //轮到下一个小孩
if(index == kid.length) {
index = 0;
}
}
/* 找到最后那个孩子圈子中的小孩 */
for(int i=0; i<kid.length; i++) {
if(kid[i] == true) {
System.out.println(i + 1);
}
}
}
}
运行结果:
436
2)面向对象的解法
/**
* 数3退1测试 类
* @author fuchs
*
*/
public class TestCount3Quit2 {
public static void main(String[] args) {
/* 创建一个500个小孩的圈子对象 */
KidCircle kc = new KidCircle(1000);
/* 创建一个小孩对象,并指向孩子圈中的第一个小孩 */
Kid k = kc.firstKid;
/* 记录报的数字(1~3) */
int countNum = 0;
/* 当人数大于1时,一直循环 */
while(kc.count > 1) {
/* 报数 */
countNum++;
/* 报到3 */
if(countNum == 3) {
countNum = 0; //清零,下次从1开始数
kc.deleteKid(k);//删除当前小孩
}
k = k.rightKid; //当前小孩指向右手边的小孩
}
/* 退出循环时,kc.count为1,即孩子圈中只有1个小孩了,
* 最后剩下的这个小孩组成的1个人的圈子中,他既是最后一个人,也可以认为是最后一个人 */
/* 打印这个圈子中的第一个小孩 */
System.out.println(kc.firstKid.id + 1);
}
}
/**
* 孩子 类
* @author fuchs
*
*/
class Kid {
int id; //每个小孩的编号
Kid leftKid; //左手边的小孩
Kid rightKid; //右手边的小孩
}
/**
* 孩子围成的圈 类
* @author fuchs
*
*/
class KidCircle {
int count = 0; //记录圈子中的人数
Kid firstKid; //圈子中的第一个小孩
Kid lastKid; //圈子中的最后一个小孩
/* 构造一个人数为num的圈子 */
KidCircle(int num) {
for(int i=num; i>0; i--) {
addKid();
}
}
/* 添加一个小孩的方法 */
void addKid() {
/* 创建一个小孩对象 */
Kid kid = new Kid();
/* 根据圈子中的人数,来记录小孩的id号 */
kid.id = count;
/* 如果圈子中还没有人 */
if(count <= 0) {
firstKid = kid; //把创建的这个小孩作为圈子中的第一个小孩
lastKid = kid; //这个小孩也是圈子中的最后一个人
kid.leftKid = kid; //这个小孩的左手边是自己
kid.rightKid = kid; //右手边的小孩也是自己
}
/* 如果圈子里已经有人了 */
else if(count > 0) {
lastKid.rightKid = kid; //这个小孩牵者最后一个小孩的右手
firstKid.leftKid = kid; //这个小孩牵着第一个小孩的左手
kid.leftKid = lastKid; //这个小孩的左手是最后一个小孩
kid.rightKid = firstKid; //这个小孩的右手是第一个小孩
lastKid = kid; //这个小孩成为最后一个小孩
}
count++; //圈子中的小孩数量增加1
}
void deleteKid(Kid kid) {
/* 如果圈子中还没有人 */
if(count <= 0) {
return; //不能删除
}
/* 圈子中有一个小孩 */
else if(count == 1) {
firstKid = lastKid = null;
}
/* 圈子中有多个小孩 */
else if(count > 1) {
kid.leftKid.rightKid = kid.rightKid; //让这个小孩右手边的小孩成为他左手边小孩右手边的小孩
kid.rightKid.leftKid = kid.leftKid; //让这个小孩左手边的小孩成为他右手边小孩左手边的小孩
/* 如果删除的小孩是圈中的第一个小孩 */
if(kid == firstKid) {
firstKid = kid.rightKid; //让第一个小孩右手边的小孩成为第一个小孩
} else if(kid == lastKid) {
lastKid = kid.leftKid; //让最后一个小孩左手边的小孩成为最后一个小孩
}
}
count--; //圈子中的小孩数量增加1
}
}
运行结果:
436