1 /* 2 约瑟环问题其实就是一个循环链表的问题 3 */ 4 #include <iostream> 5 #include<ctime> 6 using namespace std; 7 8 //动态规划的思想,有点类似解决主元素问题的思路 9 //巧妙的用0,1数组代替链表节点的删除 10 int sun1(const int N,const int C) 11 { 12 int i=0,j=0,n=N,s=0; 13 int t=0; 14 int *a=new int [N]; 15 for (i=0;i<N;i++) 16 { 17 a[i]=1; 18 } 19 20 while(0!=n) 21 { 22 s+=a[j]; //前面的数相加每加够C出列一个数 23 if(C==s) 24 { 25 a[j]=0; 26 s=0; //要清0 27 --n; 28 if(0!=n) 29 cout<<j+1<<"->"; //s[j]实际对应的是第j+1个人 30 else 31 { 32 cout<<j+1<<endl; 33 t=j+1; 34 } 35 36 } 37 //j=(j+1)%N; // 循环队列,这里处理很巧妙 38 j= (j==N-1)?0:j+1; 39 } 40 delete []a; 41 return t; 42 43 } 44 /* 45 递推的方法 46 N=1,winner=0; 47 N=i,winner=(winner(0)+C)%i; 48 winner +=1; 49 */ 50 int sun2(const int N, const int C) 51 { 52 int f=0; 53 for(int i=2;i<=N;i++) 54 { 55 f=(f+C)%i; 56 } 57 return f+1; 58 } 59 /*循环链表 */ 60 int sun3(const int N,const int C) 61 { 62 struct node 63 { 64 int num; 65 node *next; 66 node(const int i) 67 { 68 num=i; 69 next=NULL; 70 } 71 }; 72 //初始化链表 73 node *first=NULL; 74 node *opp=first; 75 for(int i=1;i<=N;i++) 76 { 77 node *t=new node(i); 78 if(first==NULL) 79 first=t; 80 else 81 opp->next=t; 82 opp=t; 83 } 84 85 opp->next=first; 86 int winner=0; 87 opp=first; 88 while(true) 89 { 90 for(int i=2;i<=C-1;i++)// 这里注意找到的是出列的节点的父节点 91 opp=opp->next; 92 node *temp=opp->next; 93 cout<<temp->num; 94 if(opp!=temp) 95 { 96 cout<<"->"; 97 //删除节点 98 opp->next=temp->next; 99 opp=opp->next; 100 delete temp; 101 } 102 else 103 { 104 winner=temp->num; 105 cout<<" "; 106 delete opp; 107 break; 108 } 109 } 110 return winner; 111 112 } 113 114 115 116 int main() 117 { 118 ios::sync_with_stdio(false); 119 int N=0,C=0; 120 cout<<"Please enter the number of people:N="; 121 cin>>N; 122 cout<<"Please enter:C="; 123 cin>>C; 124 cout<<"winner is "<<sun1(N,C)<<endl; 125 clock_t end1=clock(); 126 cout<<"winner is "<<sun2(N,C)<<endl; 127 clock_t end2=clock(); 128 cout<<(end2-end1)/float(CLOCKS_PER_SEC)<<"seconds"<<endl; 129 cout<<"winner is "<<sun3(N,C)<<endl; 130 return 0; 131 }