天梯赛L2-002

天梯赛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的整数,下一个结点是下个结点的地址。

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

模拟链表
注意:

  1. 可以数组模拟/hash表就少用map,否则容易TLE
  2. 注意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;
}

猜你喜欢

转载自blog.csdn.net/u013455437/article/details/109210528