CCCC团体程序设计天梯赛 L2-002 链表去重

记录天梯赛题目合集 跳转查看

本题题目链接

题目描述

给定一个带整数键值的链表 \(L\),你需要把其中绝对值重复的键值结点删掉。即对每个键值 \(K\),只有第一个绝对值等于 \(K\) 的结点被保留。同时,所有被删除的结点须被保存在另一个链表上。例如给定 \(L\)\(21→-15→-15→-7→15\),你需要输出去重后的链表 \(21→-15→-7\),还有被删除的链表 \(-15→15\)

输入格式
输入在第一行给出 \(L\) 的第一个结点的地址和一个正整数 \(N\)\(≤10^5\) ,为结点总数)。一个结点的地址是非负的 \(5\) 位整数,空地址 \(NULL\)\(−1\) 来表示。

随后 \(N\) 行,每行按以下格式描述一个结点:
地址 键值 下一个结点
其中地址是该结点的地址,键值是绝对值不超过 \(10^4\) 的整数,下一个结点是下个结点的地址。

输出格式
首先输出去重后的链表,然后输出被删除的链表。每个结点占一行,按输入的格式输出。

输入样例

00100 5
99999 -7 87654
23854 -15 00000
87654 15 -1
00000 -15 99999
00100 21 23854

输出样例

00100 21 23854
23854 -15 99999
99999 -7 -1
00000 -15 87654
87654 15 -1

题目解析

题目要求是将键值的绝对值重复的元素从原链表中取出组成新链表,最后输出去重后的链表和新链表。

涉及了一点链表的知识,但核心是套着链表的模拟题。从起点开始遍历链表,用一个 \(bool\) 数组来标记出现过的键值绝对值,用两个 \(vector\) 变量来分别存储不取出和要取出的结点。

最后根据顺序输出两个 \(vector\) 即可,具体实现看代码。

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <unordered_map>

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;

const ll inf = 1e18;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 10;

string s; // 起点
int n; 
unordered_map<string, pair<int, string>> a; // 要存储链表,因为地址是字符串所以使用map或者unorderd_map来哈希存取。
bool st[N]; // 标记每个键值绝对值是否出现过
struct node {
	string id;
	int val;
	string next;
};

void solve()
{
	cin >> s >> n;
	for (int i = 0; i < n; i ++) {
		string id, next;
		int val;
		cin >> id >> val >> next;
		a[id] = {val, next}; // 记录链表结点
	}
	
	vector<node> b, c;
    // 从起点遍历链表
	while (s != "-1") {
		int num = abs(a[s].first);
        // 已出现过的键值绝对值存入 vector b
		if (st[num]) {
			b.push_back({s, a[s].first, a[s].second});
		}
		else {
			st[num] = 1;
			c.push_back({s, a[s].first, a[s].second});
		}
		s = a[s].second;
	}
	
	for (int i = 0; i < c.size(); i ++) {
		if (i < c.size() - 1) cout << c[i].id << ' ' << c[i].val << ' ' << c[i + 1].id << '\n';
		else cout << c[i].id << ' ' << c[i].val << ' ' << -1 << '\n'; // 注意最后一个结点的下一个结点是-1
	}
	
	for (int i = 0; i < b.size(); i ++) {
		if (i < b.size() - 1) cout << b[i].id << ' ' << b[i].val << ' ' << b[i + 1].id << '\n';
		else cout << b[i].id << ' ' << b[i].val << ' ' << -1;
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr);
	
	int T = 1;
//	cin >> T;
	while (T --) solve();
	return 0;
}
posted @ 2025-03-24 21:29  Natural_TLP  阅读(21)  评论(0)    收藏  举报