博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj1012
阅读量:6240 次
发布时间:2019-06-22

本文共 2292 字,大约阅读时间需要 7 分钟。

Joseph
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 52097   Accepted: 19838

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

340

Sample Output

530

Source

大致题意:

有k个坏人k个好人坐成一圈,前k个为好人(编号1~k),后k个为坏人(编号k+1~2k)

现在有一个报数m,从编号为1的人开始报数,报到m的人就要自动死去。

问当m为什么值时,可以使得在出现好人死亡之前,k个坏人先全部死掉?

 

PS:当前一轮第m个人死去后,下一轮的编号为1的人 为 前一轮编号为m+1的人

   前一轮恰好是最后一个人死掉,则下一轮循环回到开头那个人报“1”

 

解题思路:

经典的约瑟夫水题

 

由于k值比较少(1~13),暴力枚举m就可以了

递推公式为:

ans[i];  //第i轮杀掉 对应当前轮的编号为ans[i]的人

ans[0]=0;

ans[i]=(ans[i-1]+m-1)%(n-i+1);   (i>1  ,  总人数n=2k 则n-i为第i轮剩余的人数)

 

正规代码

#include
#include
using namespace std;int a[30],ans[30];//第i轮杀掉 对应当前轮的编号为ans[i]的人int main(){ int n,k,m; while(scanf("%d",&k)==1&&k){ if(a[k]) {printf("%d\n",a[k]);continue;}//方便重复询问(数据范围太小) m=1;//所求的最少的报数 n=2*k;//总人数 for(int i=1;i<=k;i++){ ans[i]=(ans[i-1]+m-1)%(n-i+1);//n-i为剩余的人数,+1从下一个人开始 if(ans[i]
[0..k) 把好人杀掉了,m值不是所求 i=0; m++;//枚举m值 } } a[k]=m; printf("%d\n",m); } return 0;}

打表写法

#include
int k,a[17]={
0,2,7,5,30,169,441,1872,7632,1740,93313,459901,1358657,2504881,1245064};int main(){ while(scanf("%d",&k)==1&&k) printf("%d\n",a[k]); return 0;}

 

转载于:https://www.cnblogs.com/shenben/p/5516149.html

你可能感兴趣的文章
据说,新闻标题"沙逼北京"总算有绝对的下联了
查看>>
易讯网售后无保障
查看>>
FF上传本地图片预览
查看>>
IO流-文件传输基础
查看>>
neo4j CQL语句
查看>>
使用 mklink把apple 备份文件从c盘转移到D盘
查看>>
构造函数
查看>>
OSPF的网络类型
查看>>
raid0 raid1 raid5 三种工作模式的工作原理及特点
查看>>
Tomcat性能调优方案
查看>>
ubuntu下安装windows下的字体
查看>>
Kubernetes ReplicationController源码分析
查看>>
八大排序算法
查看>>
北京最新小学名校排名,绝对经典!
查看>>
解决js获取innerHTML无法获取value的问题
查看>>
$(this)
查看>>
cacti 安装配置 错误处理
查看>>
strong,retain,weak,assign自匹配宏
查看>>
烂泥:wiki系统confluence5.6.6安装、中文、破解及迁移
查看>>
BOM展开2
查看>>