问题描述:
已知N个人(以编号1,2,3...N分别表示)围坐在一张圆桌周围。从编号为1的人开始报数,数到M的那个人出列;他的下一个人又从1开始报数,数到M的那个人又出列;依此规律重复下去,直到剩下最后一个人。程序的意图是求出最后留下的人的编号。
/*******C++实现************/
#include<iostream>
#include<cstdlib>
#include<stdexcept>
using namespace std;
template<class T> //C++模板
struct node
{
T item;
node* next;
node(T x,node* t):item(x),next(t) {}
};
int main(int argc,char **argv)
{
if(argc<3)
throw runtime_error("invalid commandline/n");
typedef node<int> Int_Node;//类模板使用时必须显式的实例化,这点与函数模板不同。
int N=atoi(argv[1]);//atoi用于字符串转换为整形
int M=atoi(argv[2]);
Int_Node* x=new Int_Node(1,0);
x->next=x;
Int_Node *t=x;
int i=2;
for(;i<=N;i++)
x=(x->next=new Int_Node(i,t));
//循环链表建立完成时x指向最后一个结点,即编号为N的结点!
while(x!=x->next)
{
for(i=1;i<M;i++) x=x->next;
t=x->next;
x->next=t->next;
delete t;
}
cout<<x->item<<endl;
return 0;
}
/**************C语言实现****************/
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int Item;
typedef struct node* link;
struct node
{
Item item;
link next;
};
//这里将malloc函数进行包裹,主调函数(本例子就是main函数)省去重复判断调用malloc是否成功!
void* Malloc(size_t len)
{
void* p=malloc(len);
if(p==NULL)
{
printf("malloc failed/n");
exit(-1);
}
return p;
}
int main(int argc,char **argv)
{
if(argc<3)
{
printf("commandline is invalid/n");
return -1;
}
int N=atoi(argv[1]),M=atoi(argv[2]);
link x=(link)Malloc(sizeof *x);
link t=x;
x->item=1;
x->next=x;
int i=2;
for(;i<=N;i++)
{
x=(x->next=Malloc(sizeof *x));
x->item=i;
}
x->next=t;
while(x!=x->next)
{
for(i=1;i<M;++i) x=x->next;
t=x->next;
x->next=t->next;
free(t);
}
printf("the last is %d/n",x->item);
}
输出:
./a.out 9 5
8