3 约瑟夫问题
Time Limit:1000MS Memory Limit:65535K
题型: 编程题 语言: 无限制
描述
约瑟夫问题是一个经典问题,n 个人围成一圈,从第1个人开始报数,数到 m 的人出列,
再由下一个人重新从1开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈。
本题目对约瑟夫问题做了一个改动,第1个人数到m出列,第2个人数到m+1出列,第3个人数到m+2出列,
以此类推,直到所有人都出列,请你给出最后一个出列人的编号。
输入格式
两个整数n和m,均小于1000。
输出格式
最后一个出列人的编号。
输入样例
5 3
输出样例
1
静态链表方法
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<vector>
struct cir {
int vis = 0;
int next;
}cir;
int main(void) {
int n, m, j, i = 1;
cin >> n >> m;
//定义上一个 下一个 当前位
int pre=1, nex, cur = 1;
//new定义静态链表
struct cir* c;
c = new struct cir[n + 1];
//从1开始
for (int j = 1; j < n; j++) {
c[j].next = j + 1;
}
//让最后一个结构体next为1,连成环
c[n].next = 1;
//定义一个j 从1开始一直循环加到m
j = 1;
//一共循环n-1次让n-1人出圈
while (i <= n - 1) {
while (1) {
//先排除m=1的情况 如果m=1 手动处理让结构体1出圈
//如果出圈就设置vis为1标志出圈 方便后面找到最后剩下的
if (m == 1) {
c[n].next = 2;
c[1].vis = 1;
cur = 2;
break;
}
//如果 j=m则让当前cur出圈
if (j == m) {
//前一个next接cur的next
c[pre].next = c[cur].next;
//标志出圈
c[cur].vis = 1;
//让下一个成为下一次的cur
cur = nex;
break;
}
j++;
//让pre等于当前cur
pre = cur;
//让cur跳到下一个
cur = c[cur].next;
//保存cur的下一个到nex
nex = c[cur].next;
}
j = 1;
//出一次圈,m加1次
m++;
//一共循环n-1次让n-1人出圈
i++;
}
//最后从1到n找到没出圈的输出
for (j = 1; j <= n; j++) {
if (c[j].vis == 0) {
cout << j; return 0;
}
}
return 0;
}