题目很明显,是对Joseph问题的一个延伸。考察的是对单向循环列表的使用,不过计算的比较慢,所以为了防止TLE,必须打表实现。 解决算法的程序为: #include<iostream> using namespace std; typedef struct Node { int data; struct Node *next; }MyNode,*MyList; //create a loop list MyList createList(int k) { MyList p=new MyNode(); MyList q=new MyNode(); q=p; for(int i=0;i<2*k;i++) { MyNode *node=new MyNode(); node->data=i+1; node->next=NULL; p->next=node; p=node; if(i==2*k-1) { node->next=q->next; } } return q; } //Joseph void Joseph(int k) { for(int m=k+1;;m++) { bool tag=true; MyList r1=createList(k); MyList r2=r1; r1=r1->next; r2=r1; for(int i=0;i<2*k;i++) { for(int j=1;j<m;j++) { r2=r1; r1=r1->next; } //if execute a good man before a bad man,this m value is false;but we still should release all space if(i<k&&(r1->data<k+1)) { tag=false; //其实这里不应该加continue的,应该让列表中的被new的空间全都释放的,但是10往上走算得太慢了 //为了提高速度,不得已才让内存孤儿存在 continue; } r2->next=r2->next->next; free(r1); r1=r2->next; } if(tag==true) { cout<<m<<endl; break; } } } int main() { int n=0; cin>>n; while(n!=0) { Joseph(n); cin>>n; } system("pause"); return 0; } 打表程序为: #include<iostream> using namespace std; int main() { int a[]={0,2,7,5,30,169,441,1872,7632,1740,93313,459901, 1358657, 2504881, 13482720}; int n=0; cin>>n; while(n!=0) { cout<<a[n]<<endl; cin>>n; } system("pause"); return 0; }