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(甲级)2017年秋季考试

PAT(甲级)2019年春季考试 7-2 Anniversary

PAT(甲级)2021年秋季考试summary

PAT(甲级)2018年秋季考试 7-1 Werewolf - Simple Version

PAT(甲级)2020年秋季考试 7-4 Professional Ability Test