HDU Joseph【数学&&约瑟夫环】

题目链接:http://acm.hdu.edu.cn/game/entry/problem/show.php?chapterid=2&sectionid=2&problemid=2

题目大意:现在有k个好人,k个坏人,围坐在一起,并且好人在前,坏人在后,我要得到一个步长,一直走下去,先把坏人杀完

例如:输入3(好人坏人各三个)

           输出5(步长为5,踩人顺序为:5->4->6->2->3->1)

思路一:利用 取余 模拟循环转圈

代码:

import java.util.Scanner;
public class Main{
	public static void main(String[] args){
		
		Scanner in = new Scanner(System.in);
		/**
		 * 思路:不用复杂的结构,主要利用取余来模仿循环外层循环来尝试m(步长)的值,
		 * 内层循环模拟循环淘汰:点到num外,证明循环了一圈,取余|点到好人(前k个),
		 * 跳出|点到坏人,num--,因为总数-1,所以下一步不能直接跳m长(要考虑到少了
		 * 一个坑)
		 * 
		 */
		//保存循环值的数组
		int[] res = new int[16];
		//好人/坏人 人数
		while (true) {
			int k = in.nextInt();
			if (k == 0) {
				return;
			}
			if (res[k] != 0) {
				System.out.println(res[k]);
			} else {
				//循环值m
				for (int m = k+1; ; m++) {
					boolean flag = false;
					//总人数
					int sum = 2*k;
					//为什么要加m-1,可以理解为删除某个元素后,指针自动指向下一元素,所以不能再加m
					for (int j = m; ;j += m-1) {
						if (j > sum) {
							j = j % sum!=0 ? j % sum : sum;
						}
						if (j <= k) {
							break;
						} else {
							sum--;
						}
						if (sum == k) {
							flag = true;
							break;
						}
					}
					if (flag) {
						res[k] = m;
						System.out.println(m);
						break;
					}
				}
			}
		}
		
	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值