魔術師發牌以及拉丁方陣問題
阿新 • • 發佈:2021-08-02
問題描述:魔術師利用一副牌中的13張黑牌,預先將他們排好後疊放在一起,牌面朝下。對觀眾說:“我不看牌,只數數就可以猜到每張牌是什麼,我大聲數數,你們聽,不信?現場演示。魔術師將最上面的那張牌數為1,把他翻過來正好是黑桃A,將黑桃A放在桌子上,第二次數1,2,將第一張牌放在這些牌的下面,將第二張牌翻過來,正好是黑桃2,也將它放在桌子上這樣依次進行將13張牌全部翻出,準確無誤。
問題:牌的開始順序是如何安排的?
思路:建立迴圈連結串列的時候將每個節點的data都置為0;然後在發牌順序函式中輸入值的時候,設定一個變數CountNumber,這是迴圈次數,因為當牌為2時,就是去掉已經有值的節點外的第二個節點,在迴圈中可能會遇到節點中已經有值的情況,此時就要增加一次迴圈次數,所以j--;
//魔術師發牌問題 #include <stdio.h> #include <stdlib.h> #define CardNumber 13 typedef struct Node{ int data; struct Node*Next; }Node; Node* CreateLinkList(){ Node *temp; Node *target; Node *head=NULL; int i; head=(Node*)malloc(sizeof(Node)); target=head;for(i=0;i<CardNumber;i++){ temp=(Node*)malloc(sizeof(Node)); temp->data=0; target->Next=temp; target=temp; } target->Next=head->Next; free(head); return target->Next; } //發牌順序 void magician(Node*head){ Node *p=head; intj; p->data=1; int CountNumber=2; while(1){ for(j=0;j<CountNumber;j++){ p=p->Next; if(p->data!=0){ j--;//增加一次迴圈次數 } } p->data=CountNumber++; if(CountNumber==14) break; } } int main(){ Node*p; int i; p=CreateLinkList(); magician(p); for(i=0;i<CardNumber;i++){ printf("黑桃%d ",p->data); p=p->Next; } }
拉丁方陣問題;
拉丁方陣是一種n×n的方陣,方陣中恰有n種不同的元素,每種元素恰有n個,並且每種元素在一行和一列中恰好出現一次。著名數學家和物理學家尤拉使用拉丁字母來作為拉丁方陣裡元素的符號
拉T方陣因此而得名。
思路:建立有n個節點的迴圈連結串列,然後將1-n的值分別存到n個節點當中,然後在輸出的時候在內層迴圈中多加一層迴圈;
//魔術師發牌問題 #include <stdio.h> #include <stdlib.h> typedef struct Node{ int data; struct Node*Next; }Node; Node* CreateLinkList(int n){ Node *temp; Node *target; Node *head=NULL; int i; head=(Node*)malloc(sizeof(Node)); target=head; for(i=1;i<=n;i++){ temp=(Node*)malloc(sizeof(Node)); temp->data=i; target->Next=temp; target=temp; } target->Next=head->Next; free(head); return target->Next; } int main(){ Node*p,*q; int j,i,n; scanf("%d",&n); p=CreateLinkList(n); q=p; for(i=0;i<n;i++){ p=q; for(j=0;j<i;j++) p=p->Next; for(j=0;j<n;j++){ printf("%d ",p->data); p=p->Next; } printf("\n"); } }