1. 程式人生 > >PAT 1025 反轉連結串列

PAT 1025 反轉連結串列

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 (≤10​5​​)、以及正整數 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

(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 (≤10​5​​)、以及正整數 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
#include<iostream>
#include<vector>
#include<string>
#include<fstream>
#include<algorithm>
using namespace std;

struct link{
	string address;
	int data;
	string next;
};
int main()
{
	//fstream fin("D://summer//PAT//1025//input.txt", ios::in);
	//fstream fout("D://summer//PAT//1025//output.txt", ios::out);
	string begin;//開始地址
	string next;
	int n, k;//結點總個數正整數 N 、以及正整數 K 個節點反轉
	link temp;
	vector<link> l;//單鏈表
	cin >> begin >> n >> k;
	for (int i = 0; i < n; i++)
	{
		cin >> temp.address >> temp.data >> temp.next;//從檔案中讀取單鏈表
		l.push_back(temp);
	}

	next = begin;
	vector<link> x;
	while (next != "-1")
	{
		for (int i = 0; i < l.size(); i++) //順序後的連結串列
		{
			if (l[i].address == begin)
			{
				x.push_back(l[i]);
				begin = l[i].next;
				next = l[i].next;
			}
		}
	}

	//反轉
	//reverse(x.begin(), x.begin() + k);
	for (int i = 0; (i+1) * k <= x.size(); i++)
	{
		reverse(x.begin() + i*k, x.begin() + (i + 1)*k);
	}

	for (int i = 0; i < x.size(); i++)
	{
		cout << x[i].address << " " << x[i].data << " " << x[i].next << endl;
	}
	system("pause");
	return 0;
}

填坑:

1、輸出的節點 next要改

2、輸出的最後一個節點的next為-1,注意是字串!

#include<iostream>
#include<vector>
#include<string>
#include<fstream>
#include<algorithm>
using namespace std;

struct link{
	string address;
	int data;
	string next;
};
int main()
{
	//fstream fin("D://summer//PAT//1025//input.txt", ios::in);
	//fstream fout("D://summer//PAT//1025//output.txt", ios::out);
	string begin;//開始地址
	string next;
	int n, k;//結點總個數正整數 N 、以及正整數 K 個節點反轉
	link temp;
	vector<link> l;//單鏈表
	cin >> begin >> n >> k;
	for (int i = 0; i < n; i++)
	{
		cin >> temp.address >> temp.data >> temp.next;//從檔案中讀取單鏈表
		l.push_back(temp);
	}

	next = begin;
	vector<link> x;
	while (next != "-1")
	{
		for (int i = 0; i < l.size(); i++) //順序後的連結串列
		{
			if (l[i].address == begin)
			{
				x.push_back(l[i]);
				begin = l[i].next;
				next = l[i].next;
				break;
			}
		}
	}

	//反轉
	//reverse(x.begin(), x.begin() + k);
	for (int i = 0; (i+1) * k <= x.size(); i++)
	{
		reverse(x.begin() + i*k, x.begin() + (i + 1)*k);
	}
	//改next
	for (int i = 0; i < x.size() - 1; i++)
	{
		x[i].next = x[i + 1].address;
	}
	x[x.size() - 1].next = "-1";//
	
    //輸出
	for (int i = 0; i < x.size(); i++)
	{
		cout << x[i].address << " " << x[i].data << " " << x[i].next << endl;
	}
	system("pause");
	return 0;
}

  

改為int 和 scanf還是執行超時……不過耗時短了

#include<iostream>
#include<vector>
#include<string>
#include<fstream>
#include<algorithm>
using namespace std;

struct link{
	int address;
	int data;
	int next;
};
int main()
{
	//fstream fin("D://summer//PAT//1025//input.txt", ios::in);
	//fstream fout("D://summer//PAT//1025//output.txt", ios::out);
	int begin;//開始地址
	int next;
	int n, k;//結點總個數正整數 N 、以及正整數 K 個節點反轉
	link temp;
	vector<link> l;//單鏈表
	scanf("%d%d%d", &begin, &n, &k);
	//fin >> begin >> n >> k;
	for (int i = 0; i < n; i++)
	{
		scanf("%d%d%d", &temp.address, &temp.data, &temp.next);
		//fin >> temp.address >> temp.data >> temp.next;//從檔案中讀取單鏈表
		l.push_back(temp);
	}

	next = begin;
	vector<link> x;
	while (next != -1)
	{
		for (int i = 0; i < l.size(); i++) //順序後的連結串列
		{
			if (l[i].address == begin)
			{
				x.push_back(l[i]);
				begin = l[i].next;
				next = l[i].next;
				break;
			}
		}
	}

	//反轉
	//reverse(x.begin(), x.begin() + k);
	for (int i = 0; (i+1) * k <= x.size(); i++)
	{
		if ((i + 1)*k <= x.size())
			reverse(x.begin() + i*k, x.begin() + (i + 1)*k);
	}
	//改next
	for (int i = 0; i < x.size() - 1; i++)
	{
		x[i].next = x[i + 1].address;
	}
	x[x.size() - 1].next = -1;//

	for (int i = 0; i < x.size() - 1; i++)
	{
		printf("%05d %d %05d\n", x[i].address, x[i].data, x[i].next);
		//fout << x[i].address << " " << x[i].data << " " << x[i].next << endl;
	}
	printf("%05d %d -1", x[x.size()-1].address, x[x.size()-1].data);
	system("pause");
	return 0;
}

用了l.erase(l.begin() + i); 測試點1和6反而時間更長

思路:

定義一個結構體陣列來儲存一開始的連結串列

陣列下標對應連結串列的地址,這樣就不用一直迴圈來找地址了 

(注意陣列下標100000,next的定址不能在begin之後 或者 不能=a[begin].next)

#include<iostream>
#include<vector>
#include<string>
#include<fstream>
#include<algorithm>
using namespace std;

struct link{
	int address;
	int data;
	int next;
};
int main()
{
	//fstream fin("D://summer//PAT//1025//input.txt", ios::in);
	//fstream fout("D://summer//PAT//1025//output.txt", ios::out);
	int begin;//開始地址
	int next;
	int n, k;//結點總個數正整數 N 、以及正整數 K 個節點反轉
	link temp;
	link a[100000];//根據陣列下標存連結串列資料、不能少個0
	int index;
	vector<link> l;//單鏈表
	scanf("%d%d%d", &begin, &n, &k);
	//fin >> begin >> n >> k;
	for (int i = 0; i < n; i++)
	{
		scanf("%d%d%d", &temp.address, &temp.data, &temp.next);
		//fin >> temp.address >> temp.data >> temp.next;//從檔案中讀取單鏈表
		//l.push_back(temp);
		a[temp.address] = temp;
	}

	next = begin;
	vector<link> x;
	while (next != -1)
	{
		x.push_back(a[begin]);
		begin = a[begin].next;
		next = begin;//這裡要注意
	}

	//反轉
	//reverse(x.begin(), x.begin() + k);
	for (int i = 0; (i + 1) * k <= x.size(); i++)
	{
		if ((i + 1)*k <= x.size())
			reverse(x.begin() + i*k, x.begin() + (i + 1)*k);
	}
	//改next
	for (int i = 0; i < x.size() - 1; i++)
	{
		x[i].next = x[i + 1].address;
	}
	x[x.size() - 1].next = -1;//

	for (int i = 0; i < x.size() - 1; i++)
	{
		printf("%05d %d %05d\n", x[i].address, x[i].data, x[i].next);
		//fout << x[i].address << " " << x[i].data << " " << x[i].next << endl;
	}
	printf("%05d %d -1", x[x.size() - 1].address, x[x.size() - 1].data);
	system("pause");
	return 0;
}