狐狸捉兔子,约瑟夫,猴子选大王,求剩余者42

第一题:猴子选大王。

题目:有M个猴子围成一圈,每个有一个编号,编号从1到M。打算从中选出一个大王。经过协商,决定选大王的规则如下:从第一个开始,每隔N个,数到的猴子出圈,最后剩下来的就是大王。要求:从键盘输入M,N,编程计算哪一个编号的猴子成为大王

第二题:设有N个人围成一圏,并且按照顺时针方向从1到N编号,由第S个人开始进行从1到M报数,报数到第M个人时,此人出圏,再从下一个人重新开始从1到M报数,如此进行下去,直到所有的人都出圏为止。现在要求编程按照出圏的顺序,打印这N个人的顺序表。
第三题:狸捉兔子
•围绕着山顶有10个洞,狐狸要吃兔子,兔子说:“可以,但必须找到我,我就藏身于这十个洞中,你从10号洞出发,先到1号洞找,第二次隔1个洞找,第三次隔2个洞找,以后如此类推,次数不限。”但狐狸从早到晚进进出出了1000次,仍没有找到兔子。问兔子究竟藏在哪个洞里?
参考题目 2 50枚棋子围成圆圈,编上号码1,2,3,…每隔一枚棋子取出一枚,要求最后留下的一枚棋子的号码是42,那该从几号棋子开始取呢?



java实现,具体见代码:总共5个类(狐狸捉兔子单独)

一个封装的类:OneTwoClass

import java.util.LinkedList;
import java.util.List;

public class OneTwoClass {
	/**
	 * 
	 * @param m
	 *            代表总数
	 * @param n
	 *            代表第几个淘汰,出场
	 * @param flag
	 *            1代表第一题,2代表第二题
	 * @param S
	 *            代表从第几个开始
	 */
	int  findPeople(int m, int n, int flag, int S) {
		List<Integer> target = new LinkedList<Integer>(); // 创建一个整形列表
		for (int i = 0; i < m; i++) { // 初始化列表,0号放1,1号放猴子2,,m-1号放最后一只猴子
			target.add(i + 1);
		}
		int point = 0;
		int index = 1; // 标志淘汰猴子标志,当Index等于n时出场
		if (flag == 1) // flag == 1时,代表第一题
			point = 0; // 下标标志
		else if (flag == 2) // 当flag == 2时,代表第二题,下标从S-1开始
			point = S - 1;
		while (target.size() > 1) { // 当还有两只猴子以上时
			index++; //
			if (point >= target.size() - 1) // 达到尾部,重新返回初始指针处
				point = 0; // 下标又从0开始
			else
				point++;

			if (index == n) { // 判断是否是要出场的猴子
				index = 1; // 淘汰猴子标志
				if (flag == 1)
					target.remove(point); // 移除该猴子
				else if (flag == 2) { // 第二题需要打印出来
					System.out.print("  " + target.get(point));
					target.remove(point);
				}
				if (point > target.size() - 1) // 该处是为了防止移除最后一项而指针未能移到初始处而引起的exception
					point = 0;
			}
		}
//		if (flag == 1)
			System.out.println("最后猴子大王是 : " + target.get(0) + " 号");
//
//		else if (flag == 2) {
//			System.out.println("  " + target.get(0));
//		}
		return target.get(0);
	}
}



第一题的测试类:MonkeyTest


import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class MonkeyTest {

	public static void main(String[] args) {
		OneTwoClass mokey = new OneTwoClass();
		Scanner s = new Scanner(System.in);
		System.out.println("请输入猴子总数M:");
		int M = s.nextInt();
		System.out.println("请输入出场隔数N(第N个出场):");
		int N = s.nextInt();
		if (M >= 1 && N > 0){
			int last = mokey.findPeople(M, N , 1 , 1);
			System.out.println("最后猴子大王是 : " + last + " 号");
		}
		else {
			System.out.println("您的输入有误!");
		}
	}

}

第二题的测试类:TwoTest


import java.util.Scanner;

public class TwoTest {
	public static void main(String[] args) {
		OneTwoClass people = new OneTwoClass();
		Scanner s = new Scanner(System.in);
		System.out.println("请人总数	N:");
		int N = s.nextInt();
		System.out.println("请输入第几个人开始S:");
		int S = s.nextInt();
		System.out.println("请输入到第几个人淘汰 M:");
		int M = s.nextInt();
		if (N >= 1 && M > 0 && S >= 1) {
			System.out.println("出场顺序依次是:");
			int last = people.findPeople(N, M, 2, S);
			System.out.print(" " + last);
		} else {
			System.out.println("您的输入有误!");
		}
	}
}

第四题的测试类:FourTest


import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class FourTest {

	public static void main(String[] args) {
		OneTwoClass thread = new OneTwoClass();
		/*
		 * 第一个参数代表50人,第二个参数代表每2个人开始取出,第三个参数flag代表用猴子式,
		 * 第四个参数代表假如从1号开始算,即从2号开始取出,
		 */
		int last = thread.findPeople(50, 2, 1, 1);  
		int result =( (42 - last + 1 + 50) % 50 + 1);		
		//((1号 -1号返回的结果 + 42)% 50)但1号代表的是从一号开始数,从2号开始取出,故而加1
		System.out.println("若要使50人中最后剩下第42人,则需从第 " + result + "号开始取出!");
		
	}
}
结果:

若要使50人中最后剩下第42人,则需从第 7号开始取出!

第三题:狐狸捉兔子

ThreadClass


public class ThreadClass {
	public static void main(String[] args) {
		int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 洞
		int i, j, k;
		for (i = 1, j = 1; i <= 1000; j = j + i) { // i代表狐狸查找总次数
			if (j > 10) // 当大于10时求余数
				j = j % 10; // 循环
			for (k = 0; k < 10; k++)
				if (a[k] != 0)	//避免已经置为0的洞再次置为0
					if (j == a[k])// 狐狸经过的洞置0
						a[k] = 0;
			i++;
		}
		System.out.println("兔子在的洞:");
		for (k = 0; k < 10; k++)
			// 不为0就是狐狸没找的洞
			if (a[k] != 0)
				System.out.print(" " + a[k]);

	}
}

结果:

兔子在的洞:
 2 4 7 9



  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值