Joseph
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 47657   Accepted: 17949

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. 


Input

The input file consists of separate lines containing k. The last line in the input file contains 0. You can suppose that 0 < k < 14.

Output

The output file will consist of separate lines containing m corresponding to k in the input file.

Sample Input

3
4
0

Sample Output

5
30

Source

约瑟夫问题的变形,開始对题意就理解了好久。这类题目主要要找到中间的公式;这道题就要知道 当前出局的位置 = (前一个出局的位置+m-1)%(2k-(k-1);

是从0開始数。这就是一个通式;明确了这个公式这个题相当于就做出了一半;这中间另一个判别的条件,就是假设当前的位置假设<k,说明这样的情况就不满足了;

第一种方法:就直接能够对m的值进行枚举。利用判别条件,找出合适的m值;

以下是代码;这样的思路好像200ms能够过。

//暴力+枚举
#include <cstdio>
#include <cstring>
int main()
{
int k;
int ans[20];//储存当前的位置
int Joseph[20]={0}; //储存符合条件的m的值
for(k=1;k<14;k++)
{
int m=1;
memset(ans,0,sizeof(ans));
for(int i=1;i<=k;i++)
{
ans[i]=(ans[i-1]+m-1)%(2*k-i+1); //递推公式
if(ans[i]<k)
{
i=0;
m++;
}
}
Joseph[k]=m;
}
while(scanf("%d",&k)&&k!=0)
{
printf("%d\n",Joseph[k]);
}
return 0;
}

要想0ms过的,直接得出结果数组,然后再提交。

//直接枚举 0ms
#include <cstdio>
#include <cstring>
int main()
{
int k;
int Joseph[]={0,2,7,5,30,169,441,1872,7632,1740,93313,459901,1358657,2504881,1245064};
while(scanf("%d",&k)&&k!=0)
{
printf("%d\n",Joseph[k]);
}
return 0;
}

另外一种方法,要挖掘题目中的隐含条件,我看了好久都没看出来,代码是參考别人的,这样的46ms就能够过;优化了不少。

题目中的隐含条件;仅仅剩下一个坏人的时候,下一个报数的人要么是第1个人,要么是第k+1个人。所以间隔就是m=s*(k+1)或者是 m=s*(k+1)+1;

粗略的证明一下。參考别人的:(这里我也还有点没懂)

仅剩一个坏人,圈长为k+1;设下一个报数人为第一个人时的时间间隔为m1;下一个报数人为第k+1个人时的时间间隔为m2。

由 (1+m1)%(k+1)=1 得出 m1= s*(k+1);

   (k+1+m2)%(k+1)=1  得出 m2=s*(k+1)+1;

这样我们就能够对m的枚举优化剪枝,m是(k+1)的倍数或者是他的倍数+1;

#include <cstdio>
#include <cstring>
bool Joseph(int k,int m)
{
int n=2*k,x=0;
while(n>k)
{
x=(x+m-1)%n;//递推公式,算出当前出局的位置
if(x<k) //判别条件
return false;
n--;
}
return true;
}
int main()
{
int k;
int result[20]={0};
for(k=1;k<14;k++)
{
for(int i=k+1;;i+=k+1) //对m枚举进行优化
{
if(Joseph(k,i)) //m是k+1的倍数或者倍数+1
{
result[k]=i;
break;
}
else if(Joseph(k,i+1))
{
result[k]=i+1;
break;
}
}
}
while(scanf("%d",&k)&&k)
{
printf("%d\n",result[k]);
}
}

总结一下:对于这一类题型要读懂题目的题意。挖掘题目的隐含条件,多构思。理清思路才開始动手写。







poj 1012 Joseph (约瑟夫问题)的更多相关文章

  1. POJ 1012 Joseph 约瑟夫问题

    http://poj.org/problem?id=1012 早上去图书馆复习苦逼的复习....万恶的数逻.T T我还要自我安慰的说复习完了奖励回来刷水题~ 10点多的时候外面校运会大吼撑杆跳的那个. ...

  2. POJ 1012 Joseph

    Joseph Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44650   Accepted: 16837 Descript ...

  3. POJ 1012 Joseph 推导,暴力,约瑟夫环,打表 难度:2

    http://poj.org/problem?id=1012 答案以954ms飘过,不过这道题可以轻松用打表过 思路:如果我们把每个人位于数组中的原始编号记为绝对编号,每次循环过后相对于绝对编号为0的 ...

  4. POJ 1012 Joseph(打表题)

    题意:约瑟夫环的变形.要求寻找到一个杀人循环节m使后半节的坏人先被所有杀光. 直接链表模拟出结果,再打表即可: 代码:(凝视的是打表码) #include<iostream> #inclu ...

  5. poj 1012 &amp; hdu 1443 Joseph(约瑟夫环变形)

    题目链接: POJ  1012: id=1012">http://poj.org/problem?id=1012 HDU 1443: pid=1443">http:// ...

  6. poj 1012——Toseph

    提交地址:http://poj.org/problem?id=1012                                                                 ...

  7. Joseph POJ - 1012 约瑟夫环递推

    题意:约瑟夫环  初始前k个人后k个人  问m等于多少的时候 后k个先出去 题解:因为前k个位置是不动的,所以只要考虑每次递推后的位置在不在前面k个就行 有递推式 ans[i]=(ans[i-1]+m ...

  8. POJ 1012:Joseph

    Joseph Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 50068   Accepted: 19020 Descript ...

  9. (顺序表的应用5.4.3)POJ 1012(约瑟夫环问题——保证前k个出队元素为后k个元素)

    /* * POJ-1012.cpp * * Created on: 2013年10月31日 * Author: Administrator */ #include <iostream> # ...

随机推荐

  1. 【转】UITextView的使用详解

    //初始化并定义大小 UITextView *textview = [[UITextView alloc] initWithFrame:CGRectMake(20, 10, 280, 30)]; te ...

  2. Objective-C学习篇01—类的声明与实现

    Objective-C,是美国人布莱德·确斯(Brad Cox)于 1980 年年初发明的一 种程序设计语言,其与同时代的 C++ 一样,都是在 C 的基础上加入面向对象特性扩充而成的.Objecti ...

  3. Landsat元数据批量下载工具

    目录 前言 landsat数据情况简介 下载元数据 总结 一.前言        最近由于工作需要,需要下载部分landsat数据的元数据,老板大手一挥,给了十几年的landsat的path.row以 ...

  4. Hibernate 性能优化之查询缓存

    查询缓存是建立在二级缓存基础之上的,所以与二级缓存特性相似,是共享的,适合修改不是很频繁的数据 查询缓存不是默认开启的,需要设置      1.在cfg文件中配置 <property name= ...

  5. UVA 10254 - The Priest Mathematician (dp | 汉诺塔 | 找规律 | 大数)

    本文出自   http://blog.csdn.net/shuangde800 题目点击打开链接 题意: 汉诺塔游戏请看 百度百科 正常的汉诺塔游戏是只有3个柱子,并且如果有n个圆盘,至少需要2^n- ...

  6. 001.为什么选择用AngularJs开发?

    网上关于AngularJs(https://angularjs.org/)的介绍与好处已经相当多了,大家可以自己去搜索看看,很多很多. 1.疯狂的原生的App开发 在这里我主要谈一下我自己为什么要使用 ...

  7. jQuery delegate方法实现Ajax请求绑定事件不丢失

    给元素绑定click事件后 ,遇到一个问题:当执行一些ajax请求,再次调用此页面,里面的这个click事件就失效了 比如说:我的分页是一个ajax请求 但我点下一页时 后生成的元素a就没有了clic ...

  8. Scrapy使用以及Xpath的一些坑, 再入剁手

    scrapy爬虫: https:www.scrapy.org 本篇博客依托的项目: https://github.com/viciousstar/BitcointalkSpider/ 一. Scrap ...

  9. c构造函数

    构造函数   任何一们面向对象语言里都会涉及构造函数这一概念,只是实现的方式各有差异.需要这main函数之前执行一段代码是非常容易的事情,只需要声明一对象的全局变量,在构造函数可以为所欲为干你想干的事 ...

  10. SPSS基础操作

    1.数据--排序个案(按行排序),排序变量是按列排序2.现有一文件两列,销售地区(字符串或者数字)和业绩,想按地区划分文件,可以排序个案(按销售地区),也可以选择“数据--拆分文件”(注意还是在一个文 ...