PAT(甲级)2019年秋季考试 7-2 Merging Linked Lists
Posted CSU迦叶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT(甲级)2019年秋季考试 7-2 Merging Linked Lists相关的知识,希望对你有一定的参考价值。
又是老朋友链表输出题,依然采用哈希静态存储,但是这题稍复杂的是,有两条链表,但是我们可以默认link1>link2,然后让link2上的节点接着link1后面编号,并且注意link2是倒序输出的。
输出时有几个关键点:
1. gnum存储的是link1的2个节点为一组的组数,也就是,后面还可能孤着一个link2的节点
int gnum = cnt1/2;
外层for循环一共进行gnum次,其中前gnum-1次属于一种情况,不用担心-1的输出。 但是每次结束,都要判断link2是否到头。最后一组属于一种情况,再根据cnt1%2是否为0进行判断,要是为0说明link2的节点没有单独一个成组的,不为0也好办,因为也就多出一个结点。
for(int i=0;i<gnum;i++){
int j1 = i*2;
int j2 = cnt-1-i;//j2>=cnt1
if(i!=gnum-1){//不用担心-1,至少后面还有两个长链的元素
printf("%05d %d %05d\\n",node[j1].add,node[j1].data,node[j1+1].add);
printf("%05d %d ",node[j1+1].add,node[j1+1].data);
if(j2>=cnt1){
printf("%05d\\n",node[j2].add);
printf("%05d %d %05d\\n",node[j2].add,node[j2].data,node[j1+2].add);
}else printf("%05d\\n",node[j1+2].add);
}
if(i==gnum-1){
if(cnt1%2!=0){//其实后面还有1个尾巴
printf("%05d %d %05d\\n",node[j1].add,node[j1].data,node[j1+1].add);
printf("%05d %d ",node[j1+1].add,node[j1+1].data);
if(j2>=cnt1){
printf("%05d\\n",node[j2].add);
printf("%05d %d %05d\\n",node[j2].add,node[j2].data,node[j1+2].add);
}else printf("%05d\\n",node[j1+2].add);
printf("%05d %d -1\\n",node[j1+2].add,node[j1+2].data);
}else{
printf("%05d %d %05d\\n",node[j1].add,node[j1].data,node[j1+1].add);
printf("%05d %d ",node[j1+1].add,node[j1+1].data);
if(j2>=cnt1){
printf("%05d\\n",node[j2].add);
printf("%05d %d -1\\n",node[j2].add,node[j2].data);
}else printf("-1\\n");
}
}
}
2. 如何判断link2是否输出完毕了呢?
由于此处是倒序,可以根据下标是否到达了第一个结点的下标,也就是link1的长度判断。
int j2 = cnt-1-i;//j2>=cnt1
起初是22分,用这个用例测结果未达到预期
1 4 4
1 1 2
2 2 3
3 3 -1
4 1 -1
原因是,我默认link1比link2长,只有在link1<link2是才会进行重新编序号的操作,在这个过程中让总有效节点个数cnt增加,但是如果不需要重新编序,则cnt会停留在0。而后面决定link2上的节点是否已输出完时还要用到cnt,所以会出错。
AC代码
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<cstring>
using namespace std;
const int maxn = 100010;
const int SUP = 100010;//权重小于等于100
struct Node{
int add,data,next;
int no = maxn;
}node[maxn];
bool cmp(Node a,Node b){
return a.no<b.no;
}
int main(){
int s1,s2,n;
scanf("%d %d %d",&s1,&s2,&n);
int add,data,next;
while(n--){
scanf("%d %d %d",&add,&data,&next);
node[add].add = add;
node[add].data = data;
node[add].next = next;
}
int h1 = s1,cnt1 = 0;
while(h1!=-1){
node[h1].no = ++cnt1;
h1 = node[h1].next;
}
int h2 = s2,cnt2 = 0;
while(h2!=-1){
node[h2].no = ++cnt1;
cnt2 ++;
h2 = node[h2].next;
}
cnt1 = cnt1 - cnt2;
int cnt = 0;
if(cnt1<cnt2){//默认cnt1>2cnt2,让多数在前面
h2 = s2;
while(h2!=-1){
node[h2].no = ++cnt;
h2 = node[h2].next;
}
h1 = s1;
while(h1!=-1){
node[h1].no = ++cnt;
h1 = node[h1].next;
}
swap(cnt1,cnt2);
}else cnt = cnt1 + cnt2;
sort(node,node+maxn,cmp);
int gnum = cnt1/2;
for(int i=0;i<gnum;i++){
int j1 = i*2;
int j2 = cnt-1-i;//j2>=cnt1
if(i!=gnum-1){//不用担心-1,至少后面还有两个长链的元素
printf("%05d %d %05d\\n",node[j1].add,node[j1].data,node[j1+1].add);
printf("%05d %d ",node[j1+1].add,node[j1+1].data);
if(j2>=cnt1){
printf("%05d\\n",node[j2].add);
printf("%05d %d %05d\\n",node[j2].add,node[j2].data,node[j1+2].add);
}else printf("%05d\\n",node[j1+2].add);
}
if(i==gnum-1){
if(cnt1%2!=0){//其实后面还有1个尾巴
printf("%05d %d %05d\\n",node[j1].add,node[j1].data,node[j1+1].add);
printf("%05d %d ",node[j1+1].add,node[j1+1].data);
if(j2>=cnt1){
printf("%05d\\n",node[j2].add);
printf("%05d %d %05d\\n",node[j2].add,node[j2].data,node[j1+2].add);
}else printf("%05d\\n",node[j1+2].add);
printf("%05d %d -1\\n",node[j1+2].add,node[j1+2].data);
}else{
printf("%05d %d %05d\\n",node[j1].add,node[j1].data,node[j1+1].add);
printf("%05d %d ",node[j1+1].add,node[j1+1].data);
if(j2>=cnt1){
printf("%05d\\n",node[j2].add);
printf("%05d %d -1\\n",node[j2].add,node[j2].data);
}else printf("-1\\n");
}
}
}
return 0;
}
以上是关于PAT(甲级)2019年秋季考试 7-2 Merging Linked Lists的主要内容,如果未能解决你的问题,请参考以下文章
PAT(甲级)2019年秋季考试 7-3 Postfix Expression
PAT(甲级)2019年春季考试 7-2 Anniversary