約瑟夫問題
問題一:
#include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node *next; } ListNode; typedef ListNode *LinkList; LinkList initRing(int n,LinkList R); LinkList DeleteDeath(int n,int k,LinkList R); int main() { LinkList R; int n,k; printf("總人數n="); scanf("%d",&n); printf("報數上限k="); scanf("%d",&k); R=initRing(n,R); R=DeleteDeath(n,k,R); } /* 建立單循環鏈表 */ LinkList initRing(int n,LinkList R) { ListNode *p,*q; int i; R=(ListNode *)malloc(sizeof(ListNode));//把R當做頭結點,里面沒有數據值 q=R;//q為臨時變量,將頭節點賦值給q for (i=1;i<=n;i++) { p=(ListNode *)malloc(sizeof(ListNode));//給p分配空間 p->data=i;//初始化p的data q->next=p;//q是p的上一節點,將q指向p首地址 q=p;//此時p為尾節點,將p賦值給臨時變量q } p->next=R->next;//使最后一個結點指向第一個結點,構成一個循環。 return R; } LinkList DeleteDeath(int n,int k,LinkList R) { int i,j; ListNode *p,*q; p=R; for(i=1;i<n;i++)//n代表循環n次結束,全部死亡 { for(j=1;j<k;j++){ p=p->next;//p是第k-1個 (待刪除項) } q=p->next; p->next=q->next; printf("%d ",q->data); free(q); R=p; } printf("存活下來的是%d",R->data); return R; }
加入可以規定從何處開始報數的功能:
#include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node *next; } ListNode; typedef ListNode *LinkList; LinkList initRing(int n,LinkList R); LinkList DeleteDeath(int n,int k,LinkList R); int main() { LinkList R; int n,k; printf("總人數n="); scanf("%d",&n); printf("報數上限k="); scanf("%d",&k); R=initRing(n,R); R=DeleteDeath(n,k,R); } /* 建立單循環鏈表 */ LinkList initRing(int n,LinkList R) { ListNode *p,*q; int i; R=(ListNode *)malloc(sizeof(ListNode));//把R當做頭結點,里面沒有數據值 q=R;//q為臨時變量,將頭節點賦值給q for (i=1;i<=n;i++) { p=(ListNode *)malloc(sizeof(ListNode));//給p分配空間 p->data=i;//初始化p的data q->next=p;//q是p的上一節點,將q指向p首地址 q=p;//此時p為尾節點,將p賦值給臨時變量q } p->next=R->next;//使最后一個結點指向第一個結點,構成一個循環。 return R; } LinkList DeleteDeath(int n,int k,LinkList R) { int i,j,m; //由於不支持一個函數有過多傳入的參數,且新建鏈表時用不着起始位置,故我們把起始位置放在函數中定義和使用 printf("輸入開始報數的位置m:"); scanf("%d",&m); ListNode *p,*q; p=R; for(j=0;j<m;j++)//先將當前位置向后移動m位,即表示從第m個開始報數 { p=p->next; } for(i=1;i<n;i++)//n代表循環n次結束,全部死亡 { for(j=1;j<k;j++) { p=p->next;//p是第k個 (待刪除項) } q=p->next;//q指向p下一節點 p->next=q->next;//p下一節點指向q下一節點(即為空) printf("%d ",q->data);//輸出此即將被刪除的節點的值 free(q);//釋放該節點空間 R=p;//下一輪初始位置位p(0位置) } printf("存活下來的是%d",R->data);//上面循環了n-1次,1人存活,R(即為此時的p)為最后存活者 return R;//返回存活者R節點 }
C語言生成不重復的隨機數
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int n; printf("請輸入n值:"); scanf("%d",&n) ; int list[n], i,j, a; srand(time(NULL));//設置隨機數種子。 for(i = 0; i < n; i ++) { while(1) { a = rand()%10; //獲取一個0~10之間的隨機數。 for(j = 0; j < i; j ++) if(list[j] == a) break;//檢查重復,有重復則跳出此步,且不滿足下一步的條件,故而該重復值沒有被儲存下來,並且重新隨機取值。 if(j == i)//沒有重復值,保存到list中。 { list[i] = a; break; } } } for(i = 0; i < n; i ++)//打印獲取到的隨機數序列。 printf("%d,",list[i]); printf("\n"); return 0; }