UVa 133 救濟金髮放
阿新 • • 發佈:2018-12-26
題意:所有n個人圍成一個圈,一邊從1號開始逆時針數k個,出局;一邊從n號開始順時針數m個,出局。兩個同時發生。如果這兩個數到同一個人,就這個人出局。
facing inwards 面朝裡; counter 相反地,clockwise 順時針,counter-clockwise 逆時針
思路:雙向迴圈連結串列來模擬。按以前書上介紹的實現的,有一個頭指標,首尾都指向它。但這裡由於要找第k個、第m個,需要進行頭指標的判斷,所以覺得這裡不增加頭指標比較好,或者頭指標只指向頭結點,而頭結點和尾結點是互指的,不像這裡實現的頭結點和尾結點之間還有一個頭指標結點。
看很多人用資料模擬實現的。。
注意:if裡的相等判斷,用==
free同一塊記憶體多次發生未定義錯誤
指向指標的引用形參的問題。
找不出錯誤時,可以跑一下別人AC的程式,對比相同輸入的輸出。
一般發現一組不一致的或錯誤的資料時,可以試圖找到一組儘量簡單的錯誤資料,除非只對該組資料錯誤。資料越簡單,越容易除錯。如果只有很大的資料才會出錯,通常意味著程式在處理極限資料方面有問題。
#include<stdio.h> #include<malloc.h> struct Node { int data; Node *next; Node *prior; }; Node* CreateList(Node* &head, int n); Node* searchk(Node *ptr, Node* &head, int k); Node* rsearchm(Node *ptr, Node* &head, int m); void deletenode(Node *ptr); void show(Node* ptr); int main() { int n,k,m; while(scanf("%d%d%d",&n,&k,&m)==3 && (n||k||m)) { Node *head=NULL; Node *mnode=CreateList(head,n); //show(head); Node *knode=head->next; bool flag=0; while(head->next!=head) { if(flag) printf(","); knode=searchk(knode,head,k); //printf("%d\n",knode->data); mnode=rsearchm(mnode,head,m); bool b=1;//標記最後兩個deletenode別重複free if(knode!=mnode) printf("%3d%3d",knode->data,mnode->data); else { printf("%3d",knode->data); b=0;} flag=1; Node *sk=knode,*sm=mnode;//下面兩句考慮到next位置會不會恰好是要刪除的結點 knode=knode->next; while(knode==sm) knode=knode->next; mnode=mnode->prior; while(mnode==sk) mnode=mnode->prior; deletenode(sk); if(b) deletenode(sm); } printf("\n"); free(head); }//while return 0; } void show(Node* ptr) { Node *p=ptr->next; while(p!=ptr) { printf("%d\n",p->data); p=p->next; } } void deletenode(Node *ptr) { if(ptr==NULL) return; ptr->prior->next=ptr->next; ptr->next->prior=ptr->prior; free(ptr); ptr=NULL; } Node* rsearchm(Node *ptr, Node* &head, int m) {//逆序移動到當前位置的第m個元素,返回該元素位置 int i=1; Node *p=ptr; while(i<m) { if(p==head) p=p->prior; p=p->prior; i++; } if(p==head) p=p->prior; return p;/* while(p!=head && i<m) { p=p->prior; i++; } if(p==head) p=p->prior; while(i<m) { p=p->prior; i++; } if(p==head) p=p->prior; return p;*/ } Node* searchk(Node *ptr, Node* &head, int k) {//順序移動到當前位置ptr的第k個元素,返回該元素位置 (即數的這k個位置包括當前位置) int i=1; Node *p=ptr; while(i<k) { if(p==head) p=p->next; //!!! if裡面的== p=p->next; i++; } if(p==head) p=p->next; return p; } Node* CreateList(Node* &head, int n) {//順序建立n個結點,head為頭指標,next指向頭結點;並返回尾結點指標 head=(Node*)malloc(sizeof(Node)); head->next=NULL; head->data=0; head->prior=NULL; Node* ptr=head; for(int i=1;i<=n;++i) { Node* p=(Node*)malloc(sizeof(Node)); ptr->next=p; p->data=i; p->next=NULL; p->prior=ptr; ptr=p; } //ptr->next=head->next;//n的後一個結點是1 //head->next->prior=ptr;//1的前一個結點是n head->prior=ptr; ptr->next=head;//n的後一個結點是頭指標 return ptr; }