http://poj.org/problem?id=1012 (题目链接)

半年前的考试题。。任然清晰的记得那次差10分就AK。。。

题意

  约瑟夫环,有前k个好人,后k个坏人,要求使得后k个坏人先死的最小m。

Solution

  很水的约瑟夫问题。。半年前还是暴力模拟+打表。。醉了。

  无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),当n,m非常大(例如上百万,上千万)的时候,几乎是没有办法在短时间内出结果的。我们注意到原问题仅仅是要求出最后的胜利者的序号,而不是要读者模拟整个过程。因此如果要追求效率,就要打破常规,实施一点数学策略。

  为了讨论方便,先把问题稍微改变一下,并不影响原意:

  问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。

  我们知道第一个人(编号一定是m%n-1) 出列之后,剩下的n-1个人组成了一个新的约瑟夫环(以编号为k=m%n的人开始):

    k k+1 k+2 … n-2, n-1, 0, 1, 2, … k-2

  并且从k开始报0。

  现在我们把他们的编号做一下转换: 
    k –> 0 
    k+1 –> 1 
    k+2 –> 2 
    … 
    … 
    k-2 –> n-2 
    k-1 –> n-1

  变换后就完完全全成为了(n-1)个人报数的子问题,假如我们知道这个子问题的解:例如x是最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗?!!变回去的公式很简单,相信大家都可以推出来:x’=(x+k)%n

  如何知道(n-1)个人报数的问题的解?对,只要知道(n-2)个人的解就行了。(n-2)个人的解呢?当然是先求(n-3)的情况 —- 这显然就是一个倒推问题!好了,思路出来了,下面写递推公式:

  令f[i]表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n]

  递推公式: 
    f[1]=0; 
    f[i]=(f[i-1]+m)%i; (i>1)

  有了这个公式,我们要做的就是从1-n顺序算出f[i]的数值,最后结果是f[n]。因为实际生活中编号总是从1开始,我们输出f[n]+1.

  所提对于这道题我们只需枚举m然后判断即可。

代码

// poj1012
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<set>
#define MOD 1000000007
#define inf 2147483640
#define LL long long
#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
using namespace std;
inline LL getint() {
LL x=0,f=1;char ch=getchar();
while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
} int main() {
int k,a[30]={0};
while (scanf("%d",&k)!=EOF && k) {
if (a[k]) {printf("%d\n",a[k]);continue;}
int n=2*k,m=k;
int ans[30]={0};
for (int i=1;i<=k;i++) {
ans[i]=(ans[i-1]+m-1)%(n-i+1);
if (ans[i]<k) {i=0,m++;if (((m-1)/k)%2==0) m=m+k;}
}
a[k]=m;
printf("%d\n",m);
}
return 0;
}

  

【poj1012】 Joseph的更多相关文章

  1. 【模拟】【HDU1443】 Joseph

    Joseph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  2. 机器学习(Machine Learning)&深度学习(Deep Learning)资料【转】

    转自:机器学习(Machine Learning)&深度学习(Deep Learning)资料 <Brief History of Machine Learning> 介绍:这是一 ...

  3. 《Java并发编程实战》/童云兰译【PDF】下载

    <Java并发编程实战>/童云兰译[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062521 内容简介 本书深入浅出地介绍了Jav ...

  4. 【题解】 2月19日 厦门双十中学NOIP2014模拟D2 T1 采药人的切题规则

    Made by 退役的OIer 第一次写博客,写得不好 or 不清楚的可以 在下方留言,我会尽量改进的! 好啦~~~回到正题,题面见传送门 [问题描述] 采药人最近在认真切题,但回旋的转盘时常在眼前浮 ...

  5. 【原创】Java并发编程系列1:大纲

    [原创]Java并发编程系列1:大纲 一个人能力当中所蕴藏的潜能,远超过自己想象以外. 为什么要学习并发编程 随着现今互联网行业的迅猛发展,其业务复杂度.并发量也在不断增加,对程序的要求变得越来越高, ...

  6. 【转】最小生成树——Kruskal算法

    [转]最小生成树--Kruskal算法 标签(空格分隔): 算法 本文是转载,原文在最小生成树-Prim算法和Kruskal算法,因为复试的时候只用到Kruskal算法即可,故这里不再涉及Prim算法 ...

  7. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  8. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  9. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

随机推荐

  1. AC日记——热浪 codevs 1557 (最短路模板题)

    1557 热浪  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description 德克萨斯纯朴的民眾们这个夏 ...

  2. Volley(三)—— ImageRequest & Request简介

    Volley(三)—— ImageRequest & Request简介 上 篇文章我们讲 到了如何用volley进行简单的网络请求,我们可以很容易的接受到string.JsonObjec类型 ...

  3. js知识体系的梳理一

    今天简单的总结了js的一些东西,梳理下整个体系,每一次的总结都会有不同的收获:js总结一一.[获取元素]: 1.通过ID: var oBtn=document.getElementById('btn1 ...

  4. 09SpringMvc_再次讲一下SpringMvc的工作流:

    整个SpringMvc的流程图:

  5. Download the WDK, WinDbg, and associated tools

    Download the WDK, WinDbg, and associated tools This is where you get your Windows Driver Kit (WDK) a ...

  6. PBR综合小实验视频-狮子XL

    这个是上学时候录的一个策略路由小实验

  7. normal.1

    11 # coding:utf-8 def maxnum(ipstr): ipstr = ipstr.split(' ')[1] return ipstr def minnum(ipstr): ips ...

  8. 基于RESTful标准的Web Api

    微软的web api是在vs2012上的mvc4项目绑定发行的,它提出的web api是完全基于RESTful标准的,完全不同于之前的(同是SOAP协议的)wcf和webService,它是简单,代码 ...

  9. JS 之BOM

    BOM的核心对象是window,表示浏览器的一个实例. 使用框架时,window.top对象指顶层框架,也就是浏览器窗口.window.parent对象指包含当前窗口的框架,也就是父框架.window ...

  10. Lisp简明教程

    此教程是我花了一点时间和功夫整理出来的,希望能够帮到喜欢Lisp(Common Lisp)的朋友们.本人排版很烂还望多多海涵! <Lisp简明教程>PDF格式下载 <Lisp简明教程 ...