题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2211

杀人游戏

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3624    Accepted Submission(s): 1182

Problem Description
不知道你是否玩过杀人游戏,这里的杀人游戏可没有法官,警察之类的人,只有土匪,现在已知有N个土匪站在一排,每个土匪都有一个编号,从1到N,每次杀人时给定一个K值,从还活着的土匪中,编号从小到大的找到K个人,然后杀掉,继续往下,直到找遍,然后继续从剩下的土匪中,编号从小到大找到第K个活着的土匪,然后杀掉。比如,现在有10个土匪,K为3,第一次杀掉3,6,9号的土匪,第二次杀掉4,8号土匪,第三次杀掉5号土匪,第四次杀掉7号土匪,第五次杀掉10号土匪,我们看到10号土匪是最后一个被杀掉的(从1到K-1的土匪运气好,不会被杀!)。现在给定你一个N和一个K,问你最后一个被杀掉的土匪的编号是多少。
 
Input
第一行有一个T(T<=10000),接下来有T组数据,每组中包含一个N(N<2^31)和一个K(3<=K<=100&&K<N)。
 
Output
对于每组数据,输出最后被杀的土匪的编号。
 
Sample Input
1
10 3
 
Sample Output
10
 
这个题是约瑟夫问题,做法有几个,整理了以下,代码来自他人博客。
 

解法一:插数法(来源:http://www.cnblogs.com/yuyixingkong/p/3254566.html

 #include<stdio.h>
int main()
{
__int64 t,n,k,count,luck,s,p,i;
scanf("%I64d",&t);
while(t--)
{
scanf("%I64d%I64d",&n,&k);
p=k-;//插入周期eg:k=3,那么p=2;两个一插
for(s=k;s<n+1;)//s为标记,来标记luckboy的位置
{
i=(s-)/p;//计算s前面插几个
luck=s;//luck是记录上一个s的值
s=s+i;
}
printf("%I64d\n",luck);
}
return ;
}

以样例代码为例(如下图所示),即参数为10,3.S代表最后一个被杀的人,下面表示如果杀到最后一轮,3号是最后一个被杀掉的。那么倒数第二轮他应该在四号位置,并且倒数第二轮应该比倒数第一轮多一个人。依次类推,倒数第三轮他在五号位置,此时有六个人。需要注意的是S后面的人其实是可有可无的,对结果不影响,观察第三行和第二行,可以得到,输入(5,3)和(6,3)都是一样的结果,结果都是S(5)。第四行就可以得到输入(7,3,)(8,3)(9,3)都是得到S(7)。这样通过下面的流程图可以得到任意(x,3)问题的解。那么怎么得到所有的解呢。

我们可以看到,第三行比第二行新插进来1个数,而第四行比第三行多插2个,这规律就是,对于第x个位置的数,前一轮(即上图的下一行)要比现在的位置靠后 (x-1)/(k-1)个,x-1好理解,k-1怎么理解呢,k是每k个人,杀一个,杀完之后,如果要还原回原来个数的人,那么需要每k-1个人插一个。 所以对于现在第x位置的人,x的前一轮的位置就是 x+(x-1)/(k-1)。

关于x的初值,显然x最小应该等于k,一直增加到等于n,结束。以上图为例,n=10,k=3,x才开始为3,一直增长到10结束,结果为10。

n =10,k=3,a=10。其实当k=3时,n=10,是a=10的下限,我们在图中可以看出来当k=3时,n属于10~13,a=10。

同理,随便输一个数 n=10096,k=28,得到 a =9776。

符合k=28,a =9776,这样的n的范围是[9776,10137].

方法二:递归法

int f(int n,int k)
{
if(n==k) return k;
int t=f(n-n/k,k);
return t+(t-)/(k-);
}
int main()
{
int t,n,k;
scanf("%d",&t);
while(t--) scanf("%d%d",&n,&k),printf("%d\n",f(n,k));
return ;
}

这个比较难理解,需要推导数学公式。

方法三:打表法

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std; typedef __int64 LL;
LL INF=; LL save[][]; int main()
{
LL ans,b,d,mid;
for(LL i=;i<=;i++)
{
ans=i;
for(LL j=;j<;j++)
{
b=ans,d=INF;
while(b<=d)
{
mid=(b+d)/;
if(mid-mid/i == ans)
break;
if(mid-mid/i>ans)
d=mid-;
else b=mid+;
}
if( (mid-)-(mid-)/i==ans ) ans=mid-;
else ans=mid;
save[i][j]=ans;
}
}
int T;
scanf("%d",&T);
int flag,n,k,cnt;
while(T--)
{
scanf("%d%d",&n,&k);
for(int i=;;i++)
{
if(save[k][i]>n&&save[k][i-]<=n)
{
printf("%I64d\n",save[k][i-]);
break;
}
}
}
return ;
}

很暴力,性能远不如前面,但是容易想。

 

【acm】杀人游戏(hdu2211)的更多相关文章

  1. 杀人游戏(hdu2211)插入法

    杀人游戏 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  2. hdu2211杀人游戏

    Problem Description 不知道你是否玩过杀人游戏,这里的杀人游戏可没有法官,警察之类的人,只有土匪,现在已知有N个土匪站在一排,每个土匪都有一个编号,从1到N,每次杀人时给定一个K值, ...

  3. 【BZOJ-2438】杀人游戏 Tarjan + 缩点 + 概率

    2438: [中山市选2011]杀人游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1638  Solved: 433[Submit][Statu ...

  4. 丢沙包游戏(或杀人游戏)的C语言实现

    丢沙包游戏(或杀人游戏)用C语言实现: 游戏简述: 杀人游戏(或者丢沙包游戏),设定一些人(人数为:num)一起玩游戏,从某个指定的人(设定为:start)开始轮流扔沙包,扔沙包人的下一个人为1,每隔 ...

  5. 【BZOJ2438】[中山市选]杀人游戏 Tarjan+概率

    [中山市选]杀人游戏 Tarjan+概率 题目描述 ​ 一位冷血的杀手潜入\(Na\)-\(wiat\),并假装成平民.警察希望能在\(N\)个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查 ...

  6. BZOJ 2438:杀人游戏(tarjan+概率)

    杀人游戏Description一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, ...

  7. bzoj2438 杀人游戏 Tarjan强联通

    [bzoj2438][中山市选2011]杀人游戏 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人进行查证,假如查 ...

  8. BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量

    BZOJ_2438_[中山市选2011]杀人游戏 _强连通分量 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手.警察能够对每一个人 ...

  9. bzoj2438: [中山市选2011]杀人游戏(强联通+特判)

    2438: [中山市选2011]杀人游戏 题目:传送门 简要题意: 给出n个点,m条有向边,进行最少的访问并且可以便利(n-1)个点,求这个方案成功的概率 题解: 一道非常好的题目! 题目要知道最大的 ...

随机推荐

  1. PTA基础编程题目集6-5求自定类型元素的最大值 (函数题)

    原题目: 本题要求实现一个函数,求N个集合元素S[]中的最大值,其中集合元素的类型为自定义的ElementType. 函数接口定义: ElementType Max( ElementType S[], ...

  2. 在linux环境下安装redis并且搭建自己的redis集群

    此文档主要介绍在linux环境下安装redis并且搭建自己的redis集群 搭建环境: ubuntun 16.04 + redis-3.0.6 本文章分为三个部分:redis安装.搭建redis集群 ...

  3. Asp.net Core Startup Class中是如何获取配置信息的

    默认的网站构建方式 VS2015新建asp.net core项目,项目建立完成后,有两个文件,Program.cs和Startup.cs. public class Program { public ...

  4. 20155233 实验一 Java开发环境的熟悉(Linux + IDEA)

    20155233 实验一 Java开发环境的熟悉(Linux + IDEA) 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用IDEA编辑.编译.运行.调试Java程序. 实验步骤 ( ...

  5. jsp+servlet+javabean开发web项目

    一.介绍: 项目依赖包:jdbc数据库包 jsp+servlet+javabean开发web项目,是最接近web项目原生运行原理的. 但是,jsp内容混乱,项目结构复杂时,代码会混乱 二.运行原理: ...

  6. underscore.js 分析 第三天

    // Create a safe reference to the Underscore object for use below. // 为Underscore对象创建一个安全的引用 // _为一个 ...

  7. Eclipse--Maven--Dynamic Web Module 3.0 requires Java 1.6 错误

    用Eclipse创建Maven webapp项目时报错Dynamic Web Module 3.0 requires Java 1.6 错误 其实这个问题就是两者不匹配的问题Dynamic Web M ...

  8. 【mysql优化】mysql count(*)、count(1)、count(主键字段)、count(非主键字段)哪个性能最佳

    测试结果为:count(*)和count(1)基本相等,count(非主键字段)最耗性能 -- 数据量 708254select count(*) from tmp_test1;-- avg 0.22 ...

  9. sqlserver(2012)清理tempdb

    当数据库运行时间长了之后,tempdb变得特别大,几十G,受不了啊:当然我们知道重启 SQL Server服务的话,tempdb数据库会自动重新创建的,从而使 tempdb 回归到初始大小.但是这是生 ...

  10. 四、Django之模型与管理后台-Part 2

    一.数据库安装 打开mysite/settings.py配置文件,这是整个Django项目的设置中心.Django默认使用SQLite数据库,因为Python源生支持SQLite数据库,所以你无须安装 ...