1 /************************************************************************************** 2 * Function : 约瑟夫问题 3 * Create Date : 2014/04/20 4 * Author : NTSK13 5 * Email : beijiwei@qq.com 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 ",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 ",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(" 约瑟夫排列(最初位置-约瑟夫环位置): "); 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(" "); 154 fflush(stdout); 155 } 156 } 157 printf(" 请输入准备剩下的人数: "); 158 fflush(stdout); 159 scanf("%d", &alive); 160 printf("这%d人初始位置应排在以下序号: ",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 ",i+1,man[i]); 167 fflush(stdout); 168 } 169 printf(" "); 170 fflush(stdout); 171 getch(); 172 return 0; 173 } 176 #endif