**
02-线性结构1 两个有序链表序列的合并 (15分)
**
本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列。
函数接口定义:
List Merge( List L1, List L2 );
其中List结构定义如下:
typedef struct Node *PtrToNode;
struct Node {
ElementType Data; /* 存储结点数据 */
PtrToNode Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */
L1和L2是给定的带头结点的单链表,其结点存储的数据是递增有序的;函数Merge要将L1和L2合并为一个非递减的整数序列。应直接使用原序列中的结点,返回归并后的带头结点的链表头指针。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
ElementType Data;
PtrToNode Next;
};
typedef PtrToNode List;
List Read(); /* 细节在此不表 */
void Print( List L ); /* 细节在此不表;空链表将输出NULL */
List Merge( List L1, List L2 );
int main()
{
List L1, L2, L;
L1 = Read();
L2 = Read();
L = Merge(L1, L2);
Print(L);
Print(L1);
Print(L2);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
3
1 3 5
5
2 4 6 8 10
输出样例:
1 2 3 4 5 6 8 10
NULL
NULL
List Merge(List L1, List L2)
{
List Head, Rear, l1, l2;
Head = (List)malloc(sizeof(PtrToNode));
Head -> Next = NULL;
Rear = Head;
l1 = L1 -> Next;
l2 = L2 -> Next;
while(l1 && l2)
{
if(l1 -> Data < l2 -> Data)
{
Rear -> Next = l1;
Rear = Rear -> Next;
l1 = l1 -> Next;
}
else
{
Rear -> Next = l2;
Rear = Rear -> Next;
l2 = l2 -> Next;
}
}
for(;l1;l1 = l1 -> Next)
{
Rear -> Next = l1;
Rear = Rear -> Next;
}
for(;l2;l2 = l2 -> Next)
{
Rear -> Next = l2;
Rear = Rear -> Next;
}
L1 -> Next = NULL;
L2 -> Next = NULL;
return Head;
}
**
02-线性结构2 一元多项式的乘法与加法运算 (20分)
**
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。
输入样例:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例:
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0
#include <stdio.h>
#include <stdlib.h>
typedef struct PolyNode* Polynomial;
struct PolyNode
{
int coef;
int expon;
Polynomial link;
};
Polynomial ReadPoly();
void Attach(int c, int e, Polynomial *pRear);
Polynomial Add(Polynomial P1, Polynomial P2);
Polynomial Mult(Polynomial P1, Polynomial P2);
void PrintPoly(Polynomial P);
int main()
{
Polynomial P1, P2, PP, PS;
P1 = ReadPoly();
P2 = ReadPoly();
PP = Mult(P1, P2);
PrintPoly(PP);
PS = Add(P1, P2);
PrintPoly(PS);
return 0;
}
Polynomial ReadPoly()
{
Polynomial P, Rear, t;
int c, e, N;
scanf("%d", &N);
P = (Polynomial)malloc(sizeof(struct PolyNode));
P -> link = NULL;
Rear = P;
while(N--)
{
scanf("%d %d", &c, &e);
Attach(c, e, &Rear);
}
t = P;
P = P->link;
free(t);
return P;
}
void Attach(int c, int e, Polynomial *pRear)
{
Polynomial P;
P = (Polynomial)malloc(sizeof(struct PolyNode));
P->coef = c;
P->expon = e;
P->link = NULL;
(*pRear)->link = P;
*pRear = P;
}
Polynomial Mult(Polynomial P1, Polynomial P2)
{
Polynomial P, Rear, t1, t2, t;
int c, e;
if (!P1 || !P2)
return NULL;
t1 = P1;
t2 = P2;
P = (Polynomial)malloc(sizeof(struct PolyNode));
P->link = NULL;
Rear = P;
while(t2)
{
Attach(t1->coef * t2->coef, t1->expon + t2->expon, &Rear);
t2 = t2->link;
}
t1 = t1->link;
while(t1)
{
t2 = P2;
Rear = P;
while(t2)
{
c = t1->coef * t2->coef;
e = t1->expon + t2->expon;
while(Rear->link && Rear->link->expon > e)
Rear = Rear->link;
if(Rear->link && Rear->link->expon == e)
{
if(Rear->link->coef + c)
Rear->link->coef += c;
else
{
t = Rear->link;
Rear->link = t->link;
free(t);
}
}
else
{
t = (Polynomial)malloc(sizeof(struct PolyNode));
t->coef = c;
t->expon = e;
t->link = Rear->link;
Rear->link = t;
Rear = Rear->link;
}
t2 = t2->link;
}
t1 = t1->link;
}
t2 = P;
P = P->link;
free(t2);
return P;
}
Polynomial Add(Polynomial P1, Polynomial P2)
{
Polynomial P, t1, t2, Rear;
t1 = P1;
t2 = P2;
P = (Polynomial)malloc(sizeof(struct PolyNode));
P->link = NULL;
Rear = P;
while(t1 && t2)
{
if(t1->expon == t2->expon)
{
if(t1->coef+t2->coef)
{
Attach(t1->coef+t2->coef, t1->expon, &Rear);
}
t1 = t1->link; t2 = t2->link;
}
else if(t1->expon > t2->expon)
{
Attach(t1->coef, t1->expon, &Rear);
t1 = t1->link;
}
else
{
Attach(t2->coef, t2->expon, &Rear);
t2 = t2->link;
}
}
while(t1)
{
Attach(t1->coef, t1->expon, &Rear);
t1 = t1->link;
}
while(t2)
{
Attach(t2->coef, t2->expon, &Rear);
t2 = t2->link;
}
t1 = P; P = P->link; free(t1);
return P;
}
void PrintPoly(Polynomial P)
{
int flag = 0;
if(!P)
{
printf("0 0\n");
return;
}
while(P)
{
if(!flag)
flag = 1;
else
printf(" ");
printf("%d %d", P->coef, P->expon);
P = P->link;
}
printf("\n");
}
02-线性结构3 Reversing Linked List (25分)
Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.
Input Specification:
Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤10的5次幂) which is the total number of nodes, and a positive K (≤N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.
Then N lines follow, each describes a node in the format:
Address Data Next
where Address is the position of the node, Data is an integer, and Next is the position of the next node.
Output Specification:
For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
#include<stdio.h>
typedef struct unit Data;
struct unit{
int address;//地址
int data;//数据
int nextAddress;//后续元素地址
int nextIndex;//后续元素在数组中的下标
};
int reverse(Data b[],int legal,int k){//反转函数
int i,j;
int tail,ptr1,ptr2;//tail是每次逆转后的末尾的下标值
int head;
int firstTime=0;//判别是否第一次处理
ptr1=0;
ptr2=1;
if(k==1||legal==1)
return -1;
else{
for(i=0;i<legal/k;i++){// 长度为k的序列个数
for(j=0;j<k-1;j++){//逆转 后面元素指向前面元素 下标递增
b[ptr2].nextIndex=ptr1;
ptr1++;
ptr2++;
}
firstTime++;
if(firstTime==1){//若是第一次处理 记下首地址 记下末尾元素的下标
head=ptr1;
tail=0;
}
else{//若非第一次处理 则使上一次处理的末尾指向此次逆序后的首元素 更新末尾元素下标
b[tail].nextIndex=ptr1;
tail+=k;
}
if(i+1>=legal/k)//若无下次循环即剩下元素无需处理 末尾直接指向剩余元素 否则 更新下标
b[tail].nextIndex=ptr2;
else{
ptr1++;
ptr2++;
}
}
}
return head;
}
void adjust(Data b[],int legal,int head){//给逆转后的数据调整nextAddress的值
int i;
for(i=0;i<legal;i++){
if(i+1<legal){
b[head].nextAddress=b[b[head].nextIndex].address;
head=b[head].nextIndex;
}
else
b[head].nextAddress=-1;
}
}
void output(Data b[],int legal,int head){//输出
int i=0;
if(head==-1){//元素或需逆转的个数只有1个的情况 直接输出
for(i=0;i<legal;i++){
if(b[i].nextAddress==-1)
printf("%05d %d %d",b[i].address,b[i].data,b[i].nextAddress);
else
printf("%05d %d %05d\n",b[i].address,b[i].data,b[i].nextAddress);
}
}
else{
for(i=0;i<legal;i++){
if(b[head].nextAddress==-1)
printf("%05d %d %d",b[head].address,b[head].data,b[head].nextAddress);
else
printf("%05d %d %05d\n",b[head].address,b[head].data,b[head].nextAddress);
head=b[head].nextIndex;
}
}
}
int main(){
Data a[100001];//存放输入数据的数组 用下标和地址匹配进行存放
Data temp;
int FirstAddress,N,k; //首地址 元素个数 需逆转个数
int head;
int i,legal; //legal是有效元素个数
scanf("%d %d %d",&FirstAddress,&N,&k);
Data b[N];// b数组的大小为N,将按序存放各个元素
for(i=0;i<N;i++){ //输入元素到数组 a
scanf("%d %d %d",&temp.address,&temp.data,&temp.nextAddress);
a[temp.address]=temp;
if(temp.address==FirstAddress)//首地址元素 作为数组b的首元素
b[0]=temp;
}
i=0;
while(b[i].nextAddress!=-1){//按地址顺序把 a 中元素装入 b 中,并赋值nextIndex使他们按序连在一起
b[i].nextIndex=i+1;
b[i+1]=a[b[i].nextAddress];
i++;
}
legal=i+1;//合法元素个数
head=reverse(b,legal,k);
if(head!=-1)
adjust(b,legal,head);
output(b,legal,head);
return 0;
}
02-线性结构4 Pop Sequence (25分)
Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, …, N and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.
Input Specification:
Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): M (the maximum capacity of the stack), N (the length of push sequence), and K (the number of pop sequences to be checked). Then K lines follow, each contains a pop sequence of N numbers. All the numbers in a line are separated by a space.
Output Specification:
For each pop sequence, print in one line “YES” if it is indeed a possible pop sequence of the stack, or “NO” if not.
Sample Input:
5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2
Sample Output:
YES
NO
NO
YES
NO
#include <stdio.h>
#define MAXSIZE 1000
void Output(int number[], int M, int N);
int main()
{
int M, N, K;
int i, j;
int number[MAXSIZE][MAXSIZE];
scanf("%d %d %d", &M, &N, &K);
/*将数据读入*/
if(K)
{
for(i = 0; i < K; i++)
{
for(j = 0; j < N; j++)
{
scanf("%d", &number[i][j]);
}
}
}
for(i = 0; i < K; i++)
{
Output(number[i], M, N);
}
return 0;
}
void Output(int number[], int M, int N)
{
int i, j, h;
int flag = 1;
for(i = 0; i < N; i++)
{
if((number[i]) > (M + i))
{
flag = 0;
break;
}
}
int max, beforemax;
for(i = 0; i < N-2; i++)
{
max = number[i];
for(j = i+ 1; j < N-1; j++)
{
if(number[j] < max)
{
beforemax = number[j];
for(h = j+1; h < N; h++)
{
if((number[h] < max) && (number[h] > beforemax))
{
flag = 0;
break;
}
}
}
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}