问题 C: 瑞神要考研
时间限制: 1 Sec 内存限制: 128 MB提交: 230 解决: 45
[ 提交][ 状态][ 讨论版]
题目描述
瑞神要准备考研了,为了复习数据结构,瑞神在某宝上买了一本数据结构得考研辅导资料《考研数据结构---从入门到放弃》,从此瑞神开始了愉快的复(zhuang)习(bi)。
有一天,瑞神找了好多条链表来辅助自己复习,但是他在复习的过程中一不小心把链表掉在了地上,捡起来的时候链表以及断成了好多个结点,每个结点只保留了当前结点的地址、结点的值和下一个结点的地址。瑞神看着这些结点浑身难受无法复习,为了让瑞神继续复(zhuang)习(bi)下去,请你帮瑞神把链表复原。
有一天,瑞神找了好多条链表来辅助自己复习,但是他在复习的过程中一不小心把链表掉在了地上,捡起来的时候链表以及断成了好多个结点,每个结点只保留了当前结点的地址、结点的值和下一个结点的地址。瑞神看着这些结点浑身难受无法复习,为了让瑞神继续复(zhuang)习(bi)下去,请你帮瑞神把链表复原。
输入
第一行给出结点的个数n(1<=n<=100000)。
接下来n行每行给出一个结点的信息:结点地址、值和下一个结点的地址。
地址为5位数字,-1表示地址为NULL。
保证每一条链表的最后一个结点的下一个结点地址为-1。
接下来n行每行给出一个结点的信息:结点地址、值和下一个结点的地址。
地址为5位数字,-1表示地址为NULL。
保证每一条链表的最后一个结点的下一个结点地址为-1。
输出
每一行输出一条链表,只输出每个节点的值。
多条链表按照首结点地址从小到大排序。
多条链表按照首结点地址从小到大排序。
样例输入
3
00323 155 -1
00322 87 00323
00233 1 -1
样例输出
1
87 155
。。。 错了6遍 我是真服我自己
宛如一个智障
用一个集合去存链表头的地址 ; 然后用地址为下标的,值为后一个地址的数组去输出当前链表;
注意一点就是如何让s集合中存储的只有链表头部分 ,就是这个地方没有处理好 错了6次
#include <iostream>
#include<set>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=100000+5;
int a[maxn];
int num[maxn];
int main()
{
int T;
cin>>T;
set<int> s;
set<int> s2;//存储所有的 坐标的后一值,保证s存的是链头
set<int>::iterator it;
s.clear();
s2.clear();
memset(a,0,sizeof(a));
memset(num,-1,sizeof(num));
while(T--)
{
int l,r,v;
scanf("%d%d%d",&l,&v,&r);
if(s2.count(l)) //如果 当前的前一单链表地址 已经存在 说明这个值在链中,一定不是链头,就将原有l值去掉
s.erase(l);
if(s.count(r)) //如果当前后值能够在原先已存储的链头中找到,就说明这个链头值该去掉
s.erase(r);
if(!s2.count(l))// 必须保证当前链没有前一个值存在
{
s.insert(l);
}
s2.insert(r);//将尾放入
a[l]=r;
num[l]=v;
}
// for(it=s.begin();it!=s.end();it++)
// cout<<*it<<" ";
// cout<<endl;
for(it=s.begin();it!=s.end();it++)
{
int t=*it;//从链头开始
int flag=0;
for(int i=t;;i=a[i])
{
if(i==-1)//读取到链尾结束
{break;
}
if(!flag)
{
printf("%d",num[i]);
flag=1;
}
else
{
printf(" %d",num[i]);
}
}
printf("\n");
}
return 0;
}
两组测试数据 经典的
5
656 55 6
6 6565 -1
556 22 656
222 545 -1
553 11 -1
3
00323 155 -1
00322 87 00323
00233 1 -1