约瑟夫环问题
总时间限制:
1000ms
内存限制:
1000kB
描述
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
输入
8 1 3 (n=8 k=1 m=3 )
输出
7 (剩下的那个)
样例输入
8 3 1
样例输出
7
#include<iostream>
#include<cstring>
using namespace std;
/*自定义结构
* struct Node是在一起的,括号外面的Node,*nextList都是变量
* 这些变量的类型就是struct Node
* 结构体里可以有构造*/
typedef struct Node{
int data;
struct Node *next;
Node(){
data = 0;
next = NULL;
}
}Node, *nextList;
/*约瑟夫处理
* 利用的是循环链表的方法
* 这不是最简便的,还可以用递归的方式解决
* */
int yuesefu(int n,int k,int m){
//因为题目要求的是输出最后一个数,所以把所有出数列的数一次存到数组中去
int *a=new int[n];
//pre ,p一前一后方便删除,用p来确定k的定位和m的定位
/*基本思路
* 1.首先建立一个长度为n的循环链表(注意创建方法,利用了一个当前指针,临时指针)
* 2.找到开始的位置k
* 3.从k往后找到m的位置并删除,并把m处位置的编号存到数组里
* */
nextList p,pre,curr;
p = new Node();
p ->data = 1;
p ->next = p;
curr=p;
for(int i=2;i<=n;i++){
nextList temp=new Node();
temp ->data=i;
temp ->next=curr->next;
curr->next=temp;
curr=temp;
}
pre=curr;//p在第一个pre在最后一个(这样说不恰当,因为他是循环的)
for(int i=k-1;i>0;i--){
/*这里的k-1和 后面的m-1都是为了让 p来作为定位后的位置*/
pre=p;
p=p->next;
}
int count=0;
for(int i=n;i>0;i--){
for(int i=m-1;i>0;i--){
pre=p;
p=p->next;
}
pre->next=p->next;
a[count]=p->data;
delete p;
p=pre->next;
count++;
}
return a[count-1];
}
int main()
{
int n,k,m;
cin>>n;
cin>>k;
cin>>m;
cout<<yuesefu(n,k,m);
return 0;
}
运行结果: