1 /**************************************************************************************
2 * Function : 约瑟夫问题
3 * Create Date : 2014/04/20
4 * Author : NTSK13
5 * Email : [email protected]
6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性。
7 任何单位和个人不经本人允许不得用于商业用途
8 * Version : V0.1
9 ***************************************************************************************
10
11 题目:
12 约瑟夫问题
13
14 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出
15 圈子,问最后留下的是原来第几号的那位
16 分析:
17 //My anser:
18 常规解法,模拟数数自杀过程。自杀的人下次数数直接跳过。
19 **************************************************************************************/
20 #include<stdio.h>
21
23 #define MY_FUNC 1
24 #if MY_FUNC
25
27 #define N 3//数到3
28 #define M 41
29 int data[]={0};
30
32 int remain(int n);
33 //the first solution:
34 int main()
35 {
36 int ret=0;
39 ret=remain(M);
40
41 printf("The last remain number is: %d \n",ret);
42 fflush(stdout);//修复Eclipse printf()不能显示的小bug
45 return 0;
46 }
47
48
49 int remain(int n)
50 {
51 int i=0,j=0,die=0;
52 int current=1,k=1;55 for(j=0;j<n;j++)
56 data[j]=j+1;
57
59 while(die<n)
60 {
61 if(current==N+1)//顺序数数123,123,....
62 current=1;
65 if(current==N)//数到3的时候,要移除一个不为0的数,为0 代表人已自杀死去
66 {
67 j=i;
68 if(j>n)
69 j=j%n;
70 while(1)//remove a death
71 {
72 if(data[j]!=0)
73 {
74 data[j]=0;
75 printf("第%d个死去的人编号是: %d \n",k++,j+1);
76 fflush(stdout);
77 die++;
78 break;
79 }
80 else
81 {
82 j++;
83 if(j==n)
84 j=0;
85 }
86 }
87 if(die==n)
88 break;
89 }
90 else//数数序列号不为3的时候,继续数数,但是要跳过死去的人
91 {
92 while(1)//jump death
93 {
94 if(data[i]!=0)
95 break;
96 else
97 {
98 i++;
99 if(i==n)
100 i=0;
101 }
102 }
103 }
104
105
106 current++;//计数加一
107 i++; //
108 if(i==n)
109 i=0;
110 }
111
112 return j+1;
113 }
114 #else
115 /************************************************************************************/
116
117
118 //the second solution:
119
120 #include <stdio.h>
121 #include <stdlib.h>
122 #define N 41
123 #define M 3
124 int main()
125 {
126 int man[N]={0};
127 int count=1;
128 int i=0,pos=-1;
129 int alive=0;
130 while(count<=N)
131 {
132 do{
133 pos=(pos+1) % N; //环状处理
134 if(man[pos]==0)
135 i++;
136 if(i==M) //报数3的人
137 {
138 i=0;
139 break;
140 }
141 }while(1);
142 man[pos]=count;
143 count++;
144 }
145 printf("\n约瑟夫排列(最初位置-约瑟夫环位置):\n");
146 fflush(stdout);
147 for(i=0;i<N;i++)
148 {
149 printf("%d-%d ",i+1,man[i]);
150 fflush(stdout);
151 if(i!=0 && i%10==0) //每输出10个则换行
152 {
153 printf("\n");
154 fflush(stdout);
155 }
156 }
157 printf("\n\n请输入准备剩下的人数:\n");
158 fflush(stdout);
159 scanf("%d", &alive);
160 printf("这%d人初始位置应排在以下序号:\n",alive);
161 fflush(stdout);
162 alive=N-alive;
163 for(i=0;i<N;i++)
164 if(man[i]>alive)
165 {
166 printf("初始序号:%d,约瑟夫环序号:%d\n",i+1,man[i]);
167 fflush(stdout);
168 }
169 printf("\n");
170 fflush(stdout);
171 getch();
172 return 0;
173 }176 #endif
经典算法之约瑟夫问题,码迷,mamicode.com