ACM-约瑟夫问题
来源:互联网 发布:淘宝卖家心酸 编辑:程序博客网 时间:2024/04/19 16:29
问题描述
约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从 1 开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。
输入数据
每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m, n < 300)。最后一行是:
0 0
输出要求
对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号
输入样例
6 212 48 30 0
输出样例
517
解题思路
初一看,很可能想把这道题目当作数学题来做,即认为结果也许会是以 n 和 m 为自变量的某个函数 f(n,m),只要发现这个函数,问题就迎刃而解。实际上,这样的函数很难找,甚至也许根本就不存在。用人工解决的办法就是将 n 个数写在纸上排成一圈,然后从 1 开始数,每数到第 m 个就划掉一个数,一遍遍做下去,直到剩下最后一个。有了计算机,这项工作做起来就会快多了,我们只要编写一个程序,模拟人工操作的过程就可以了。
用数组 anLoop 来存放 n 个数,相当于 n 个数排成的圈;用整型变量 nPtr 指向当前数到的数组元素,相当于人的手指;划掉一个数的操作,就用将一个数组元素置 0 的方法来实现。人工数的时候,要跳过已经被划掉的数,那么程序执行的时候,就要跳过为 0 的数组元素。需要注意的是,当 nPtr 指向 anLoop 中最后一个元素(下标 n-1)时,再数下一个,则nPtr 要指回到数组的头一个元素(下标 0),这样 anLoop 才象一个圈。
参考程序
#include <iostream>using namespace std;#define MAX_NUM 300int aLoop[MAX_NUM+10]; int main(){int n,m,i;while(true){cin>>n>>m;if(!n && !m){break;}for(i=0;i<n;i++){aLoop[i] = i+1;}int nPtr = 0;//每次循环将 1 个猴子全赶出圈子,最后被赶出的就是猴王for(i=0;i<n;i++){int nCounted = 0;while(nCounted < m){//数出 m 个猴子while(aLoop[nPtr] == 0){//跳过已经出圈的猴子nPtr = (nPtr + 1)%n;//到下一个位置}nCounted++;//找到一只猴子nPtr = (nPtr + 1)%n;//到下一个位置}nPtr--;//上面最后因为到了下一位置,所以这里要回退一个位置if(nPtr < 0){nPtr = n-1;}if(i == n-1){//最后一只出圈的猴子cout<<aLoop[nPtr]<<endl;}aLoop[nPtr]=0; //猴子出圈}}return 0;}
0 0
- acm--约瑟夫环问题
- ACM-约瑟夫问题
- [ACM Steps] Joseph 约瑟夫环问题
- ACM模板——约瑟夫问题
- 【ACM经典01】约瑟夫环问题---STL解法
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)
- ACM:数论专题(3)——约瑟夫问题
- ACM复习(3)1139 约瑟夫环问题
- [ACM]约瑟夫环
- 约瑟夫问题、约瑟夫环
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- Collection接口API
- 关于js中 alert(1&&2)的 输出(研究了半天,是懂非懂吧)
- 遍历集合
- 如何消除内存泄漏
- Java写爬虫
- ACM-约瑟夫问题
- 计划
- 使用TreeSet
- PAT L2-003
- [2017/3/13]阿里面试总结
- linux命令 cat <<- _EOF_ 输出多行文本
- POJ2112-Optimal Milking
- 数组冒泡
- ssh连接慢