b_pat_分享 & 链表排序 & 链表去重(链表模拟)
sharing
思路
照常输入,然后先遍历第一个链表,且将第一个链表的结点都的属性设置为访问过vis=true;再从第二条链表的开头开始遍历,遇到第一个vis=true的结点node则输出node.val,返回
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
struct node {
int next=-1, vis;
} A[N];
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int s1,s2,n,addr,next;; cin>>s1>>s2>>n;
char val;
for (int i=0; i<n; i++) {
cin>>addr>>val>>next;
A[addr]={next, false};
}
for (int i=s1; i!=-1; i=A[i].next) A[i].vis=1;
for (int i=s2; i!=-1; i=A[i].next) if (A[i].vis) {
return printf("%05d", i), 0;
}
printf("-1");
return 0;
}
Linked List Sorting
第一行首先包含一个整数 N,表示总节点数量,然后包含链表头节点的地址。
接下来 N 行,每行描述一个节点的信息,格式如下:
Address Key Next
其中 Address 是节点地址,Key 值是一个整数,Next 是下一个节点的地址。
现在,给出一个链表,请你按照 Key 值升序的顺序将链表重新排序。
思路
投机取巧将node全部弄到一个vector中排序,信誓旦旦地写啦,但打的时候忘记了这样排序A[i]的next还是原来的next(即未排序时的指向),所以输出的时候输出A[i+1]的addr
#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
struct node {
int addr, val, next=-1;
} A[N];
bool cmp(node& a, node& b) {
return a.val<b.val;
}
vector<node> l_sort(int head_addr) {
vector<node> v;
for (int i=head_addr; i!=-1; i=A[i].next) {
v.push_back(A[i]);
}
sort(v.begin(), v.end(), cmp);
return v;
}
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n,head_addr; cin>>n>>head_addr;
for (int i=0; i<n; i++) {
int addr, val, next; cin>>addr>>val>>next;
A[addr]={addr, val, next};
}
auto v=l_sort(head_addr);
if (v.empty()) {
printf("0 -1");
} else {
printf("%d %05d\n", v.size(), v[0].addr);
for (int i=0; i<v.size(); i++) {
if (i==v.size()-1) printf("%05d %d -1\n", v[i].addr, v[i].val);
else printf("%05d %d %05d\n", v[i].addr, v[i].val, v[i+1].addr);
}
}
return 0;
}
Reversing Linked List
给定一个常数 K 和一个单链表 L,请你在单链表上每 K 个元素做一次反转,并输出反转完成后的链表。
如果链表最后一部分不足 K 个元素,则最后一部分不翻转。
思路
这题不能一边输入一边将节点push到vector中,因为你不知道哪个是头部结点,所以要输入完毕后再从头指针开始找结点
#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
struct node {
int addr, val, next=-1;
} A[N];
void reverse_k(vector<node>& v, int l, int r) {
while (l<r) {
swap(v[l], v[r]);
l++, r--;
}
}
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int head_addr, n, k; cin>>head_addr>>n>>k;
vector<node> v;
for (int i=0; i<n; i++) {
int addr,data,next; cin>>addr>>data>>next;
A[addr]={addr,data,next};
}
int p=head_addr;
while (p!=-1) {
v.push_back(A[p]);
p=A[p].next;
}
for (int i=0; i+k-1<v.size(); i+=k) reverse_k(v,i,i+k-1);
for (int i=0; i<v.size(); i++) {
if (i==v.size()-1) printf("%05d %d -1\n", v[i].addr, v[i].val);
else printf("%05d %d %05d\n", v[i].addr, v[i].val, v[i+1].addr);
}
return 0;
}
Deduplication on a Linked List
给定一个单链表 L,链表上的每个节点都存有一个键值,你应该删掉其中拥有重复键值绝对值的节点。
也就是说,对于每个值 K,只保留键值或键值绝对值为 K 的第一个节点。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
struct node {
int addr, val, next=-1;
} A[N];
bool vis[N];
vector<node> ans;
vector<node> remove_and_get_dup(vector<node>& v) {
vector<node> dup;
for (int i=0; i<v.size(); i++) {
if (vis[abs(v[i].val)]) {
dup.push_back(v[i]);
} else {
vis[abs(v[i].val)]=1;
ans.push_back(v[i]);
}
}
return dup;
}
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int head_addr, n; cin>>head_addr>>n;
for (int i=0; i<n; i++) {
int addr,data,next; cin>>addr>>data>>next;
A[addr]={addr,data,next};
}
vector<node> v;
int p=head_addr;
while (p!=-1) {
v.push_back(A[p]);
p=A[p].next;
}
auto dup=remove_and_get_dup(v);
for (int i=0; i<ans.size(); i++) {
if (i!=ans.size()-1) printf("%05d %d %05d\n", ans[i].addr, ans[i].val, ans[i+1].addr);
else printf("%05d %d -1\n", ans[i].addr, ans[i].val);
}
for (int i=0; i<dup.size(); i++) {
if (i!=dup.size()-1) printf("%05d %d %05d\n", dup[i].addr, dup[i].val, dup[i+1].addr);
else printf("%05d %d -1\n", dup[i].addr, dup[i].val);
}
return 0;
}
Splitting A Linked List
给定一个单链表,请编写程序将链表元素进行分类排列,使得所有负值元素都排在非负值元素的前面,而 [0,K] 区间内的元素都排在大于 K 的元素前面。
但每一类内部元素的顺序是不能改变的。
例如:给定链表为 18→7→-4→0→5→-6→10→11→-2
,K 为 10,则输出应该为 -4→-6→-2→7→0→5→10→18→11
思路
用三个vector分别存各类元素最后的输出很麻烦,直接遍历3次原始vector更简单
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
struct node {
int addr, val, next=-1;
} A[N];
vector<node> rearrange(vector<node>& v, int k) {
vector<node> ans;
for (int i=0; i<v.size(); i++) if (v[i].val<0) ans.push_back(v[i]);
for (int i=0; i<v.size(); i++) if (v[i].val>=0 && v[i].val<=k) ans.push_back(v[i]);
for (int i=0; i<v.size(); i++) if (v[i].val>k) ans.push_back(v[i]);
return ans;
}
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int head_addr, n, k; cin>>head_addr>>n>>k;
for (int i=0; i<n; i++) {
int addr,data,next; cin>>addr>>data>>next;
A[addr]={addr,data,next};
}
vector<node> v;
int p=head_addr;
while (p!=-1) {
v.push_back(A[p]);
p=A[p].next;
}
auto ans=rearrange(v, k);
for (int i=0; i<ans.size(); i++) {
printf("%05d %d", ans[i].addr, ans[i].val);
if (i!=ans.size()-1) printf(" %05d\n", ans[i+1].addr);
else printf(" -1\n");
}
return 0;
}