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

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

找规律

约瑟夫环问题变形。

在这个约瑟夫环问题中,固定每次间隔两人,10个人,杀人顺序为2,4,6,8,10,3,7,1,9,最后剩下5

定义一种运算J^m(n) 表示 m次嵌套 J(  J( J(n) )

好像J^2(10) = J(J(10)) = J(5) = 3

而m和n的最大值是 10^9

这个问题 主要是能快速算出 J(n),不难想到如果能算出J(n),可以暴力地一步一步迭代下去做m次,容容易发现不用做m次,因为J(1) = 1,当n降到1的时候,m再大都没意义了

可以发现这个问题是指数递减的,m<=10^9 是个纸老虎

 

同样地可以打表看看J(n)的值,一看就能看到规律

对于一个范围的n  ,  [  2^k , 2^(k+1)  )  (左闭右开区间)

可以发现里面的J(n) 依次为  1,3,5,7,9,11 …………2^(k+1) -1 

这样就得到了公式  J(n) = 1+(n - 2^k)*2   要求  2^k <= n < 2^(k+1)

所以我们可以先保存所有的2^k,当然得到n的时候在找2^k也是可以的

 

用上面的公式,不断地算J(n),算m次即可,过程中如果n=1,那么就可以跳出不用再算了

 

#include 
#include
typedef long long ll;ll tk[50+10];void init_tk(){ tk[0]=1; for(int i=1; i<=40; i++) tk[i] = tk[i-1] * 2;// for(int i=0; i<=40; i++)// printf("%I64d\n",tk[i]);}int search(ll n){ for(int i=0; i<=40; i++) if(tk[i] <= n && tk[i+1] > n) return i; return -1;}int main(){ init_tk(); ll n,m; while(scanf("%lld%lld",&n,&m)!=EOF) { if(!n && !m) break; while(n>1 && m) { int b = search(n); ll ans = 1 + (n - tk[b])*2; n = ans; m--; } printf("%lld\n",n); } return 0;}

 

转载地址:http://iwtlx.baihongyu.com/

你可能感兴趣的文章
Clojure:让我兴奋的编程语言
查看>>
《IPv6精髓(第2版)》——第6章 QoS6.1 QoS基础
查看>>
《Adobe Illustrator CC经典教程》—第0课0.13节使用“外观”面板
查看>>
N 个免费 DevOps 开源工具,没用过,至少应该了解!
查看>>
《有效的单元测试》一2.4 独立的测试易于单独运行
查看>>
IBM 宣布向 Node 基金会捐赠 Express 框架
查看>>
《好学的C++程序设计》——1.1 计算机怎样计数
查看>>
Docker技术入门与实战(第2版)3.2 查看镜像信息
查看>>
《妥协的完美主义:优秀产品经理的实践指南(卷二)》一2.3 团队内部组织管理...
查看>>
《Ansible权威指南 》一1.3 为什么选择Ansible
查看>>
《STM32库开发实战指南:基于STM32F4》----3.2 STM32能做什么
查看>>
《Adobe Flash CS5中文版经典教程》——1.14复习
查看>>
《 短文本数据理解》——1.3短文本理解框架
查看>>
oracle中使用SQL递归语句
查看>>
《HTML5移动Web开发实战》—— 1.2 确定网站的适用移动设备
查看>>
《C++ 黑客编程揭秘与防范(第2版)》——6.3 PE结构的3种地址
查看>>
一位真正的科学思想家: 纪念人工智能之父Marvin Minsky教授
查看>>
《JavaScript设计与开发新思维》——2.4 关键的开发方法
查看>>
IDG2016TMT战略:大量资本将投向人工智能、消费升级、泛娱乐
查看>>
《精通移动App测试实战:技术、工具和案例》一2.2 JUnit在Android开发中的应用...
查看>>