編程題目: PAT 1025. 反轉鏈表 (25)


1025. 反轉鏈表 (25)

時間限制
300 ms
內存限制
32000 kB
代碼長度限制
8000 B
判題程序
Standard
作者
CHEN, Yue

給定一個常數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;
}





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM