1025. 反轉鏈表 (25)
給定一個常數K以及一個單鏈表L,請編寫程序將L中每K個結點反轉。例如:給定L為1→2→3→4→5→6,K為3,則輸出應該為3→2→1→6→5→4;如果K為4,則輸出應該為4→3→2→1→5→6,即最后不到K個元素不反轉。
輸入格式:
每個輸入包含1個測試用例。每個測試用例第1行給出第1個結點的地址、結點總個數正整數N(<= 105)、以及正整數K(<=N),即要求反轉的子鏈結點的個數。結點的地址是5位非負整數,NULL地址用-1表示。
接下來有N行,每行格式為:
Address Data Next
其中Address是結點地址,Data是該結點保存的整數數據,Next是下一結點的地址。
輸出格式:
對每個測試用例,順序輸出反轉后的鏈表,其上每個結點占一行,格式與輸入相同。
輸入樣例:00100 6 4 00000 4 99999 00100 1 12309 68237 6 -1 33218 3 00000 99999 5 68237 12309 2 33218輸出樣例:
00000 4 33218 33218 3 12309 12309 2 00100 00100 1 99999 99999 5 68237 68237 6 -1
起初我定義好結構體node用於存每個節點的信息,直接順次輸入並通過push_back,加入到vector<node> vin中,然后找出鏈排序,邏輯上沒問題結果一提交代碼遇到各種段錯誤,運行超時,BlaBla.. = =#,看起來問題大大的,於是回過頭調整重新來寫。將錄入方式改掉,由於結點地址為5位數,也就只00000~99999,於是索性定義vector大小為100000,而vector的index就作為初始輸入時候的address,這樣可以一定程度緩解運行的時間,然而還是不行;於是又把cin,cout全部換掉為scanf,printf,還是會有運行結果錯誤的問題,考慮可能輸入的節點並不都有效,一定程度緩解問題,最后注意輸入首地址為-1的情況,以及輸出最后一組值的next為-1,終於AC了。。囧。再總結一下在處理這個問題的大致過程。
- 設置錄入的vector足夠大,直接把vector的index與節點的address匹配,這在節點數很少的情況下可用;
- 從給定頭結點指針開始,順序找到整個鏈,存儲在vsorted,要注意有些節點可能是廢節點,所以排序后找出來的鏈長度可能小於初始錄入的節點數目
- 將排序后的節點每K個為單位錄入到要輸出的最后結果的vector中(我表示為vout),注意剩余不足K個節點順序添加到后邊;
- 修改除最后一個節點之外的所有節點的next指針,並輸出每個節點信息;
- 輸出最后一個節點信息,注意next為-1
/* http://pat.zju.edu.cn/contests/pat-b-practise/1025 反轉鏈表 */ #include<iostream> #include<vector> #include<cstdio> using namespace std; struct node { int add; int data; int next; }; int main() { vector<node> vin(100000);//輸入時暫存節點 vector<node> vsorted;//暫存排序后的結果 vector<node> vout;//最后的結果 node temp; int first,N,K; scanf("%d%d%d",&first,&N,&K); for(int i = 0;i<N;i++)//輸入 { //cin>>temp.add>>temp.data>>temp.next; scanf("%d%d%d",&temp.add,&temp.data,&temp.next); vin[temp.add]=temp; } if(first == -1) //首地址為-1.直接輸出 { printf("-1\n"); } else { int nextAdd = first; while(nextAdd !=-1) { vsorted.push_back(vin[nextAdd]); nextAdd = vin[nextAdd].next; } int Nnew = vsorted.size();//排序后的鏈的大小,不一定等於N,因為可能存在廢點不在鏈上 int right = K-1; while(right < Nnew) { for(int i=right;i>right-K;i--) { vout.push_back(vsorted[i]); } right += K; } for(int i = right-K+1;i<Nnew ;i++) { vout.push_back(vsorted[i]); } for(int i =0;i<Nnew-1;i++) { vout[i].next = vout[i+1].add; printf("%05d %d %05d\n",vout[i].add,vout[i].data,vout[i].next); //cout<<setw(5)<<setfill('0')<<vout[i].add<<" "<<vout[i].data<<" "<<setw(5)<<setfill('0')<<vout[i].next<<endl; } printf("%05d %d %d\n",vout[Nnew-1].add,vout[Nnew-1].data,-1);//最后地址-1 陷阱之一 //cout<<setw(5)<<setfill('0')<<vout[Nnew-1].add<<" "<<vout[Nnew-1].data<<" "<<vout[Nnew-1].next<<endl; } system("pause"); return 0; }