题干略,话说这个约瑟夫好贱啊,坑了自己士兵,然后自己投降了
1:自创答案
int lastOne(int N){
// 将数组所有值赋值为0 代表没自杀
int a[MAXSIZE] = {0}, i;
int outCount = 0, num = 1;
for(i=1; outCount<N-1; i = (i == N ? 1 : i+1)){
if(a[i] == 0){
if(num == 3){
num = 0;
a[i] = 1;
++outCount;
}
++num;
}
}
// 循环找到 没有被删除的元素
for(int i=1; i<=N; ++i){
if(a[i] == 0){
return i;
}
}
}
2:数组法实现,人员从0开始编号
// 不符合题意的“标准答案”
void jsf(int a[], int n, int m){
int i, j, k=0;
for(i=0; i<n; ++i){
j = 1;
while(j<m){
while(a[k] == 0){
k = (k+1) % n;
}
++j;
k = (k+1) % n;
}
while(a[k] == 0){
k = (k+1) % n;
}
a[k] = 0;
printf("%d ", k);
}
}
3:循环链表实现
// 循环链表法适合大规模数据,时间复杂度较低是O(n),数组法是O(n^2)
// 固定 100个人 数到3的人去死 1: 没死 0: 死
void jsf_linked(Node* head){
// 注意: 用a存储结果,注意跳过头节点, p->data 存储了结点的编号 1...100
int t=0; // 统计删了几个了
int a[100];
Node* p = head->next;
while(t<100){
for(int i=1; i<=3; ++i){
if(i==3){
while(p->data == 0){
p = p->next;
if(p == head){
p = p->next;
}
}
a[t] = p->data;
p->data = 0;
// ↓
p = p->next;
if(p == head){
p = p->next;
}
// ↑ 这一部分可以去掉
++t;
}else{
while(p->data == 0){
p = p->next;
if(p == head){
p = p->next;
}
}
p = p->next;
if(p == head){
p = p->next;
}
}
}
}
for(int i=0; i<100; ++i){
printf("%d ", a[i]);
}
}