约瑟夫环

来源:互联网 发布:外商投资网络支付机构 编辑:程序博客网 时间:2024/04/26 20:00

约瑟夫问题可以用数组、队列、循环链表等模拟实现,也可以通过递推公式来求解

下面选取了两道很经典的题目:

poj-1012-Joseph

这道题目如果用模拟的话,数据的处理不是很方便,所以要用递推公式的方法

people[0]=0,m=1;for(int i=1;i<=k;i++){people[i]=(people[i-1]+m-1)%(2*k-i+1);if(people[i]<k){i=0;m++;}} 
people[0]表示起点从0号开始(虽然题目要求人的编号是从1开始,但是从0开始比较方便计算),在循环体内是这个约瑟夫环的一个递推公式,people[i]表示被踢出的第i个人的编号,这个编号是由上一个被踢出人的编号移动m个位置得到,若这个位置超出了2*k个人的范围就要对这个数进行取余保证它在这个合理的范围

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
#include<stdio.h>int main(){int k,m,people[30]={0},J[20]={0};while(scanf("%d",&k),k){if(J[k]!=0){printf("%d\n",J[k]);continue;}people[0]=0,m=1;for(int i=1;i<=k;i++){people[i]=(people[i-1]+m-1)%(2*k-i+1);if(people[i]<k){i=0;m++;}} J[k]=m;printf("%d\n",J[k]);}return 0;}

约瑟夫问题10e100版(from vijios)  (摘自百度百科)

描述 Description
n个人排成一圈。从某个人开始,按顺时针方向依次编号。从编号为1的人开始顺时针“一二一”报数,报到2的人退出圈子。这样不断循环下去,圈子里的人将不断减少。由于人的个数是有限的,因此最终会剩下一个人。试问最后剩下的人最开始的编号。
输入格式 Input Format
一个正整数n,表示人的个数。输入数据保证数字n不超过100位。
输出格式 Output Format
一个正整数。它表示经过“一二一”报数后最后剩下的人的编号。
样例输入 Sample Input
9
样例输出 Sample Output
3
时间限制 Time Limitation
各个测试点1s
注释 Hint
样例说明
当n=9时,退出圈子的人的编号依次为:
2 4 6 8 1 5 9 7
最后剩下的人编号为3
初见这道题,可能会想到模拟。可是数据实在太大啦!!
我们先拿手来算,可知n分别为1,2,3,4,5,6,7,8...时的结果是1,1,3,1,3,5,7,1...
有如下规律:从1到下一个1为一组,每一组中都是从1开始递增的奇数,且每组元素的个数分别为1,2,4...
这样就好弄了!!
原创粉丝点击