已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列,的中位数指A(N−1)/2的值,即第⌊个数(A0为第1个数)。
输入格式:
输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。
输出格式:
在一行中输出两个输入序列的并集序列的中位数。
输入样例1:
5
1 3 5 7 9
2 3 4 5 6
输出样例1:
4
输入样例2:
6
-100 -10 1 1 1 1
-50 0 2 3 4 5
输出样例2:
1
#include<stdio.h> #include<stdlib.h> #define ERROR 0 typedef int ElemType; typedef struct LNode{ ElemType Data; struct LNode * Next; }LNode,* List; List Create_L(int N); //给定长度的链表的创建 List Union_L(List L1,List L2); //两个链表合并,不去重 int DuplicataRM_Ptf(List L); //链表去重,并返回中位数 int main(){ int N; List L,L2,L1; scanf("%d",&N); L1=Create_L(N); L2=Create_L(N); L=Union_L(L1,L2); if(!L) printf("NULL"); else printf("%d",DuplicataRM_Ptf(L)); return 0; } List Create_L(int N){ //定长序列创建 List L,head; int i; if(N<=0) return NULL; L=(List)malloc(sizeof(LNode)); head=L; scanf("%d",&L->Data); for(i=0;i<N-1;i++){ L->Next=(List)malloc(sizeof(LNode)); L=L->Next; scanf("%d",&L->Data); } L->Next=NULL; return head; } List Union_L(List L1,List L2){ //链表合并不去重 List L,head; L=(List)malloc(sizeof(LNode)); //建立一个类似头节点的节点,便于后续链接,最后删去 head=L; while(L1&&L2){ if(L1->Data<=L2->Data){ //由小到大排列序列 L->Next=L1; L=L->Next; L1=L1->Next; } else { L->Next=L2; L=L->Next; L2=L2->Next; } } if(L1){ //L1拼接有剩余或者输入的L2为空 L->Next=L1; L=head; head=head->Next; free(L); return head; } else if(L2){ //L2拼接有剩余或者输入的L1为空 L->Next=L2; L=head; head=head->Next; free(L); return head; } else{ //对应于输入的两个链表均为空的情况 free(L); head=NULL; return head; } } int DuplicataRM_Ptf(List L){ //去重并输出中位数 List head=L,pro; int temp,count=1,result,i; //temp记录data,随推进后移,count记录去重后生成的链表元素个数 temp=L->Data; //result为最终中位数结果 pro=L; while(pro->Next){ L=pro->Next; if(temp==L->Data){ //若两节点元素相同 if(!(L->Next)){ //且此节点为最后一个节点 free(L); pro->Next=NULL; break; } else{ //此节点非最终节点 pro->Next=L->Next; free(L); } } else{ //两节点元素不同,temp后移 temp=L->Data; pro=L; count++; } } temp=(count+1)/2; for(i=0;i<temp;i++){ result=head->Data; head=head->Next; } return result; }对于此题,由于所学知识限制,使用了C语言链表进行编写,篇幅很长,且在最终提交时最后一个编译点提示答案错误,但是在本地的编译中结果均正确。此题此种写法最终得分只有21分(25分),此问题还未解决,近期会做修改。