题目链接:点击打开链接
题意:中文题意;
题解:强模拟。
详细看代码注解(详细):
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
struct node //记录初始链表
{
int key;
int next; // 下一个的位置
}a[101000];
struct node2 // 储存删除后的链表
{
int address; // 自己的位置
int key;
}b[101000];
int m=0; // 记录有多少个被删除的
int vis[100100]={0};
void delet(int pre,int next) // 一个dfs pre是上一个的地址,next是当前地址
{
int f=0;
if(next==-1) // 若当前的地址为 -1 返回
return ;
if(vis[abs(a[next].key)]==0) // 若 当前地址的值为未出现过 ,标记一下
{
vis[abs(a[next].key)]=1;
}
else // 出现的话就删除这个节点
{
a[pre].next=a[next].next; // 删除节点很简单,把当前的next,赋值给上一个next。
b[m].address=next; // 删除列表的中m的的地址赋值为next
b[m].key=a[next].key; //
m++;
f=1; //标记一下
}
if(f)
delet(pre,a[next].next); // 若删除节点,下一次的pre为这次的pre。下次的next为这次next
else
delet(next,a[next].next); // 若未删除节点 ,下一次的pre为这次的next。下次next为这次next
}
void print1(int start)
{
if(start==-1)
return ;
if(a[start].next==-1)
printf("%05d %d %d\n",start,a[start].key,a[start].next);
else
printf("%05d %d %05d\n",start,a[start].key,a[start].next);
print1(a[start].next);
}
void print2()
{
for(int i=0;i<m-1;i++)
{
printf("%05d %d %05d\n",b[i].address,b[i].key,b[i+1].address);
}
printf("%05d %d -1\n",b[m-1].address,b[m-1].key);
}
int main()
{
int n,start,tstart,key,tnext;
scanf("%d%d",&start,&n);
while(n--)
{
scanf("%d%d%d",&tstart,&key,&tnext); // 把数组下标变成自己的地址
a[tstart].key=key;
a[tstart].next=tnext;
}
delet(-1,start); //开始判重函数
print1(start);
if(m>1)
print2();
return 0;
}