题目
输入样例:
00100 01000 7
02233 2 34891
00100 6 00001
34891 3 10086
01000 1 02233
00033 5 -1
10086 4 00033
00001 7 -1
输出样例:
01000 1 02233
02233 2 00001
00001 7 34891
34891 3 10086
10086 4 00100
00100 6 00033
00033 5 -1
解题思路
1.如何链在一起:把顺序结构当作链式结构的方法
把数组的下标作为5位数字的地址
link linkall[100005];//下标是为输入的地址
链表的结构体为{地址(编号,即数组的下标);数据;下一跳地址}
//记录自己的编号,数据,下一跳
//实际上自己的编号也是数组的下标,使得顺序结构可被当作链式结构使用
typedef struct link{
int id, data, next;
}link;
这样顺序结构就可以通过下标被当作链式结构使用
2.如何合并在一起:只要根据长短表的顺序,隔两个一输出短表地址即可
- 第一个元素的每个id及其data先输出
- 接着 next,next的id和data输出
- 当有一表输出完后,再把未输出完的那个表输出完
- 最后留着-1单独输出
子函数
1.输入
for (int i = 0; i < N; i++){
scanf("%d%d%d", &id, &data, &next);
//实际上自己的编号也是数组的下标,使得顺序结构可被当作链式结构使用
linkall[id].id = id;
linkall[id].data = data;
linkall[id].next=next;
}
2.把一子表链起来
按子表的顺序存放(0空着,1~n),最后返回子表长度
int Linking(int start,link L[]){//链接表1表2
int id = start;//根据头元素地址(下标)找到链的头元素
int len = 0;//从1开始,这样长度正确,合并时不需要-1
while (id != -1){
L[++len] = linkall[id];
id = L[len].next;//跳到下一跳
}
return len;
}
2.两表合并
i代表长表的当前编号,j代表短表的当前序号
-
当两表都未输出完时,即i<=Llen&&j>=1
按序输出长表,当长表序号i%2==0时,插入一个短表的
-
当有一表输出完后,再把未输出完的那个表输出完
-
最后留着-1单独输出
void unionlink(link Short[],int Slen,link Long[],int Llen){//合并两表
//第一个元素的每个id及其data先输出
//接着 next,next的id和data输出
//最后留着-1单独输出
int j = Slen,i=1;//短表j,长表i的下标
printf("%05d %d ", Long[i].id, Long[i].data);
while (++i<=Llen&&j>=1){
printf("%05d\n%05d %d ", Long[i].id, Long[i].id, Long[i].data);
if (i%2==0){
printf("%05d\n%05d %d ", Short[j].id, Short[j].id,Short[j].data);
j--;
}
}
//写while(i++<=Llen)的话在判断完i<=Llen之后就i++了,不可以)
while (i <= Llen){//若i表未输出完
printf("%05d\n%05d %d ", Long[i].id, Long[i].id, Long[i].data);
i++;
}
while (j >= 1){//若j表未输出完
printf("%05d\n%05d %d ", Short[j].id, Short[j].id, Short[j].data);
j--;
}
printf("-1\n");
return;
}
AC代码
#include<stdio.h>
#include<stdlib.h>
#include<string>
using namespace std;
//记录自己的编号,数据,下一跳
//实际上自己的编号也是数组的下标,使得顺序结构可被当作链式结构使用
typedef struct link{
int id, data, next;
}link;
link linkall[100005];//下标是为输入的地址
link link1[100005], link2[100005];//下标是在该链的位置,方便合并
int l1,l1len,l2,l2len,start,N;
int Linking(int start,link L[]){//链接表1表2
int id = start;//根据头元素地址(下标)找到链的头元素
int len = 0;//从1开始,这样长度正确,合并时不需要-1
while (id != -1){
L[++len] = linkall[id];
id = L[len].next;//跳到下一跳
}
return len;
}
void unionlink(link Short[],int Slen,link Long[],int Llen){//合并两表
//第一个元素的每个id及其data先输出
//接着 next,next的id和data输出
//最后留着-1单独输出
int j = Slen,i=1;//短表j,长表i的下标
printf("%05d %d ", Long[i].id, Long[i].data);
while (++i<=Llen&&j>=1){
printf("%05d\n%05d %d ", Long[i].id, Long[i].id, Long[i].data);
if (i%2==0){
printf("%05d\n%05d %d ", Short[j].id, Short[j].id,Short[j].data);
j--;
}
}
//写while(i++<=Llen)的话在判断完i<=Llen之后就i++了,不可以)
while (i <= Llen){//若i表未输出完
printf("%05d\n%05d %d ", Long[i].id, Long[i].id, Long[i].data);
i++;
}
while (j >= 1){//若j表未输出完
printf("%05d\n%05d %d ", Short[j].id, Short[j].id, Short[j].data);
j--;
}
printf("-1\n");
return;
}
int main(){
scanf("%d%d%d", &l1, &l2, &N);
int id, data, next;
for (int i = 0; i < N; i++){
scanf("%d%d%d", &id, &data, &next);
//实际上自己的编号也是数组的下标,使得顺序结构可被当作链式结构使用
linkall[id].id = id;
linkall[id].data = data;
linkall[id].next=next;
}
l1len = Linking(l1, link1);
l2len = Linking(l2, link2);
if (l1len>l2len)
unionlink(link2, l2len, link1, l1len);
else
unionlink(link1, l1len, link2, l2len);
system("PAUSE");
return 0;
}