算法笔试题(二):约瑟夫环问题
来源:互联网 发布:微信拼车源码 编辑:程序博客网 时间:2024/05/22 06:05
有N个人围成一圈,第一个人从1开始报数,报到M的人出列,求最后一个出列的人。
先将这个题目转换成数学问题:设有n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数 (用数学方法解的时候需要注意应当从0开始编号,因为取余会取到0解。)
实质是一个递推,n个人中最终留下来的序号与n-1个人中留下来的人的序号有一个递推关系式。
假设除去第k个人,则
0, 1, 2, 3, ..., k-2, k-1, k, ..., n-1 // 原始序列 (1)
0, 1, 2, 3, ..., k-2, , k, ..., n-1 // 除去第k人,即除去序号为k-1的人 (2)
k, k+1, ..., n-1, 0, 1, ..., k-2 // 以序号k为起始,从k开始报0 (3)
0, 1, ..., n-k-1, n-k, n-k+1, ..., n-2 // 作编号转换,此时队列为n-1人 (4)
变换后就完完全全成为了(n-1)个人报数的子问题,注意(1)式和(4)式,是同一个问题,不同的仅仅是人数。比较(4)和(3),不难看出,0+k=k, 1+k=k+1, ... ,(3)式中'0'后面的数字,((n-3)+k)%n=k-3,((n-2)+k)%n=k-2, 对于(3)式中'0'前面的数字,由于比n小,也可看作(0+k)%n=k, (1+k)%n=k+1, 故可得出规律:
设(3)中某一数为x' , (4)中对应的数为x,则有:x'=(x+k)%n.
设x为最终留下的人序号时,队列只剩下1人时,显然x=0; 此时可向前回溯至2人时x对应的序号,3人时x对应的序号……直至n人时x的序号,即为所求。
递归法表示如下:
#include <stdio.h>int main(){ int N,M,s=0; scanf("%d%d",&N,&M); for (int i=2;i<=N;++i) s=(s+M)%i; printf("%d\n",s+1); return 0;}
0 0
- 算法笔试题(二):约瑟夫环问题
- [笔试]约瑟夫环问题
- 【Java笔试题】约瑟夫环问题
- 约瑟夫环算法问题
- 算法----约瑟夫环问题
- 算法 约瑟夫环问题
- [算法]约瑟夫环问题
- (算法)约瑟夫环问题
- 实习题-约瑟夫环问题(二)
- 约瑟夫环C++笔试题
- 经典算法<二>约瑟夫问题 C++实现
- 华三笔试约瑟夫环问题
- 约瑟夫环问题,经典笔试,鄙视
- 约瑟夫环问题研究(二)
- 约瑟夫环问题算法集锦
- c# 算法-------约瑟夫环问题
- 算法题/约瑟夫环
- 华为上机笔试题之约瑟夫环
- TCP和UDP浅析
- 用*输出菱形
- Vijos P1706 舞会
- android活动的启动模式
- c#串口通信之adc数据采集
- 算法笔试题(二):约瑟夫环问题
- C++编程入门系列之十八(C++程序设计必知:作用域和可见性)
- JavaScriptDOM文档对象模型
- 对.net系统架构改造的一点经验和教训
- 全局变量和局部变量
- c语言printf()输出格式 用法联系
- Linux Shell 脚本 自动备份 Mysql 数据库
- android之调用摄像头与相册
- Xamarin跨平台开发中遇到的问题以及解决方法