天梯赛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的整数,下一个结点是下个结点的地址。
输出格式: 首先输出去重后的链表,然后输出被删除的链表。每个结点占一行,按输入的格式输出。
模拟链表
注意:
- 可以数组模拟/hash表就少用map,否则容易TLE
- 注意string转int时负号的处理,以及空地址为-1长度不是5
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int l[N],w[N],w0[N],ad[N],num[N],sum1=0,sum2=0;
string a0[N],da[N];
bool vis[200010];
int ch(string s){
return (s[4]-'0')*10000+(s[3]-'0')*1000+(s[2]-'0')*100+(s[1]-'0')*10+s[0]-'0';
}
int main(){
string f,s;
int n,p,chs,chf;
cin>>f>>n;
ad[ch(f)]=1,da[n+1]="-1",da[++sum1]=f;
for(int i=1;i<=n;i++){
cin>>f>>p>>s;
chf=ch(f);
if(s[0]!='-') chs=ch(s);
else chs=-1;
if(chf>=0&&!ad[chf]) ad[chf]=++sum1,da[sum1]=f;
if(chs>=0&&!ad[chs]) ad[chs]=++sum1,da[sum1]=s;
w[ad[chf]]=p;
if(chs>=0) l[ad[chf]]=ad[chs];
else l[ad[chf]]=n+1;
}
int x=1,x0=0;
while(da[x]!="-1"){
if(!vis[abs(w[x])]){
num[abs(w[x])]=++sum2;
vis[abs(w[x])]=1;
if(x0) cout<<da[x]<<endl<<da[x]<<" "<<w[x]<<" ";
else cout<<da[x]<<" "<<w[x]<<" ";
}
else{
w0[++w0[0]]=w[x];
a0[w0[0]]=da[x];
}
x0=x,x=l[x];
}
cout<<-1<<endl;
a0[w0[0]+1]="-1";
for(int i=1;i<=w0[0];i++)
cout<<a0[i]<<" "<<w0[i]<<" "<<a0[i+1]<<endl;
return 0;
}