108 lines
1.7 KiB
Markdown
108 lines
1.7 KiB
Markdown
### 写法1-暴力写法 使用数组来模拟队列
|
||
|
||
```c
|
||
#include <stdio.h>
|
||
|
||
/*
|
||
约瑟夫环,人数n,编号m
|
||
|
||
队列 先进先出
|
||
a 3 1 2
|
||
|
||
头 下标
|
||
尾 下标
|
||
*/
|
||
//rear尾巴 front头
|
||
int queue[200] = {0};
|
||
int rear=0, front=0;
|
||
//用来拿到队列最前面的元素值
|
||
int get(){
|
||
int temp = queue[front];
|
||
queue[front++] = 0;
|
||
return temp;
|
||
}
|
||
//用来在队列末尾差值
|
||
void put(int n){
|
||
queue[rear++] = n;
|
||
}
|
||
//打印队列当前状态
|
||
void print(){
|
||
int i;
|
||
for(i=0;i<200;i++){
|
||
if(queue[i] != 0){
|
||
printf("%d ", queue[i]);
|
||
}
|
||
}
|
||
printf("\n");
|
||
}
|
||
//判断队列是否为空
|
||
int isEmpty(){
|
||
int count = 0;
|
||
int i;
|
||
for(i=0;i<200;i++){
|
||
if(queue[i] != 0){
|
||
count++;
|
||
}
|
||
}
|
||
return count;
|
||
}
|
||
int main(){
|
||
int n, m;//n人数 m为弹出的编号
|
||
int i, count = 0;
|
||
scanf("%d %d", &n, &m);
|
||
for(i=1;i<=n;i++){
|
||
put(i);
|
||
}
|
||
print();
|
||
while(isEmpty()){
|
||
count++;
|
||
if(count % m == 0){
|
||
printf("%d ", get());
|
||
}else{
|
||
put(get());
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
```
|
||
|
||
### 写法2-循环队列 使用数组模拟循环队列
|
||
|
||
```c
|
||
#include <stdio.h>
|
||
|
||
/*
|
||
使用数组模拟循环队列
|
||
*/
|
||
|
||
int main(){
|
||
|
||
int joseph[100] = {0};
|
||
int n, m, count = 0;//n:人数 m:编号数 count:已出局的人数
|
||
int i = 1, k = 0;//i:用来遍历数组 k用来记录已经报数的编号
|
||
printf("请输入人数以及编号数:");
|
||
scanf("%d %d", &n, &m);
|
||
for(i = 0; i < n;i++){
|
||
joseph[i] = i+1;//标记为1 则为非空代表当前下标编号有人
|
||
}
|
||
|
||
i = 0;
|
||
while(n > count){
|
||
if(joseph[i]){
|
||
k++;//报数
|
||
if(k%m == 0){//判断是否弹出
|
||
printf("%d ", joseph[i]);
|
||
joseph[i] = 0;//标记为0 代表当前下标的人已经弹出
|
||
count ++;
|
||
}
|
||
}
|
||
i = (i+1)%n;
|
||
}
|
||
printf("\n");
|
||
|
||
return 0;
|
||
}
|
||
```
|
||
|