一、Description

The Joseph's problem is notoriously known. For those who are not familiar with the original problem: from among n people, numbered 1, 2, . . ., n, standing in circle every mth is going to be executed and only the life of the last
remaining person will be saved. Joseph was smart enough to choose the position of the last remaining person, thus saving his life to give us the message about the incident. For example when n = 6 and m = 5 then the people will be executed in the order 5, 4,
6, 2, 3 and 1 will be saved.



Suppose that there are k good guys and k bad guys. In the circle the first k are good guys and the last k bad guys. You have to determine such minimal m that all the bad guys will be executed before the first good guy.

二、问题分析

        刚开始的时候没看懂英文,找了个翻译:约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的人的序号为5,4,6,2,3。最后剩下1号。假定在圈子里前K个为好人,后K个为坏人,你的任务是确定这样的最少M,使得所有的坏人在第一个好人之前被杀掉。这道题感觉不容易,看了很多提示才有点感觉。

       开始的时候总想着用什么数据结构实现这个环,什么链表,栈之类的。又总是琢磨从0开始还是从1开始,傻逼逼地在那比对公式的输出结果数字。后来发现完全没有必要,因为好人与坏人总是分在两个K内的。好人在小的那一部分,坏人在较大的那部分。所以只要下个要杀的人>k就可以继续循环。这里比较坑爹的是,测试数据里面有相同的K,如果不用记忆化存储的话,可能会超时。所以,这里好多人就干脆打表了。

       什么是打表呢?如果第一个测试用例让你求第100个,那么你可以将前100个数据在自己电脑里算好再存起来,这样如果题目再问到小于100的情况,就我们就可以直接输出了,相当于查表输出,时间耗时就自然少的多了。如果第二个测试用例让我们求第200个,那么我们就从第101个算起,算出的结果继续存起来,以备下一次的实用,如此类推,这个存起来的过程就叫做打表。(打表法貌似被不少人鄙视)

      不用打表其实也是可以过的,前辈们总结了三点,再次小弟引用一下:

            1.要kill的人的位置公式p=(p+m-1)%rest+1

            2.kill的位置<k就break,此时剩下的人rest等于k就成功

            3.m不要递增,如6个人,m取1,2,3第一次就杀了好人了,没意义。m是k+1的整数倍或者k+1的整数倍加1,这样会提高不少。
import java.util.Scanner;

public class Poj1012_Joseph {

	public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
int res[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//1~14,0位置不存放
int k=0;
while((k = cin.nextInt()) != 0){
int m=0;
if(res[k]==0){
while(true){
if(m/k==0)
m += k+1;
else
m ++;
int rest=2 * k;
int pos=0;
while(true){
pos=(pos+m-1)%rest+1; //位置公式
if(pos>k){
pos--;
rest--;
}else{
break;
}
}
if(rest==k){
res[k]=m;
break;
}
}
}
System.out.println(res[k]);
}
}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

Poj1012_Joseph的更多相关文章

随机推荐

  1. elasticsearch从入门到出门-05-集群之踩坑

    自己搭的集群, 设备: win10 + ubuntu 16 的虚拟机一个: 下载的版本:elasticsearch-5.2.0 win10 解压下就好了,不说了. ubuntu 上,我想说多了都是泪! ...

  2. [转载]Hibernate如何提升数据库查询的性能

    目录(?)[-] 数据库查询性能的提升也是涉及到开发中的各个阶段在开发中选用正确的查询方法无疑是最基础也最简单的 SQL语句的优化 使用正确的查询方法 使用正确的抓取策略 Hibernate的性能优化 ...

  3. linux 基础-变量,shell基本语法

    变量 定义变量 your_name="runoob.com" #变量名和等号之间不能有空格 使用变量 your_name="qinjx" echo $your_ ...

  4. 第6条:在单次切片操作内,不要同时指定start、end和stride

    核心知识点: 1.使用负步进可以反转取值字符串及ASCII. 2.stride最好不要与start和end用在一起,会降低代码可读性. 除了基本的切片操作之外,python还提供了somelist[s ...

  5. Kattis - fire2 【BFS】

    第二组样例: 题意 给出一个起始位置,然后要跑到这幢建筑物的外面,上下左右四个方向,只要是空地 就可以走 走一步 花费一秒 然后有若干串火苗,每一秒钟 会向上下左右 四个方向的空地 蔓延 但是 逃跑的 ...

  6. 用linux搭建ranzhi环境

    一.安装红帽6.5 1.安装时需选择桥接模式: 2.选择自定义,在设置中将镜像文件(ISO)选择进去: 3.安装时选择[桌面]安装(在/etc/inittab文件中,若id=5则为桌面模式,id=3为 ...

  7. UITableViewCell高度自适应的关键点

    iOS开发中对于UITableViewCell高度自适应的文章已经很多很多,但如果cell内容比较复杂,刚使用autolayout配置自使用时还是总不能一次性成功. KEY POINT 这里只说设置的 ...

  8. TMS Scripter importtool的使用

    uses ap_DateUtils; showmessage(dayof(now)); //注册delphi对象或变量 : IDEScripter1   IDEScripter1.AddConstan ...

  9. BZOJ 1965 [Ahoi2005]SHUFFLE 洗牌:快速幂 + 逆元

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1965 题意: 对于扑克牌的一次洗牌是这样定义的,将一叠N(N为偶数)张扑克牌平均分成上下两 ...

  10. js中innerText/value/innerHTML三个属性的区别

    在做一个两个窗口之间的简单信息交互时遇见了一点问题,导致信息无法正常的传递. 最后发现问题是在innerText和value这两个属性上,先简单的总结记录一下几个相似的属性的作用: 1.innerTe ...