PAT甲级1097 Deduplication on a Linked List (25 分)思路
- 题意:给出一个链表的首地址和n(n个结点,其中不一定每个结点都属于此链表),接下去给出各个结点的首尾地址及结点的值,要求去掉这个链表中权值绝对值相同的重复的数据(只保留最开始出现的),输出去重后的链表和去掉的元素组成的新的链表,都须按原链表顺序输出。
- 思路:应用静态链表的知识,同时需要用到散列表知识和结构体排序
- step1:存入各个结点的信息,同时得到有效的链表,将有效的结点做标记。
- step2:创建一个散列表,初值都为零,用来记录此节点权值的绝对值之前是否出现过,接下去遍历整个链表。
- step3:当链表中元素满足题意时,validnum++,不满足题意(重复)时,emptynum++,对链表按照cmp的规则进行排序。
- step4:cmp规则的定义是对order小的先输出出来。在先前的标记中,有效结点的order标记为validnum,maxn+emptynum,无效结点标记为2*maxn。
- step5:输出。
代码如下
#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
struct Node
{
int addr,next,data;
int order;
}node[maxn];
bool cmp(Node x,Node y)
{
return x.order<y.order;
}
int s[100010]={0};
int main()
{
for(int i=0;i<maxn;i++)
node[i].order=2*maxn;
int begin,n;
int addr;
scanf("%d%d",&begin,&n);
for(int i=0;i<n;i++)
{
scanf("%d",&addr);
node[addr].addr=addr;
scanf("%d%d",&node[addr].data,&node[addr].next);
}
int p=begin;
int validnum=0,emptynum=0,count=0;
while(p!=-1)
{
if(s[abs(node[p].data)]==0)
{
s[abs(node[p].data)]=1;
node[p].order=validnum++;
}
else
node[p].order=maxn+emptynum++;
p=node[p].next;
count++;
}
sort(node,node+maxn,cmp);
if(count==0)
{
printf("-1\n");
}
else
{
for(int i=0;i<validnum;i++)
{
if(i==validnum-1)
printf("%05d %d -1\n",node[i].addr,node[i].data);
else
printf("%05d %d %05d\n",node[i].addr,node[i].data,node[i+1].addr);
}
for(int i=validnum;i<count;i++)
{
if(i==count-1)
printf("%05d %d -1\n",node[i].addr,node[i].data);
else
printf("%05d %d %05d\n",node[i].addr,node[i].data,node[i+1].addr);
}
}
return 0;
}