【数据结构】第三周

目录

碰撞的小球

三元组最短距离

两个有序单链表的合并

单链表数据排序

多项式相加


碰撞的小球

【问题描述】

      数轴上有一条长度为L(L为偶数)的线段,左端点在原点,右端点在坐标L处。有n个不计体积的小球在线段上,开始时所有的小球都处在偶数坐标上,速度方向向右,速度大小为1单位长度每秒。

      当小球到达线段的端点(左端点或右端点)的时候,会立即向相反的方向移动,速度大小仍然为原来大小。

      当两个小球撞到一起的时候,两个小球会分别向与自己原来移动的方向相反的方向,以原来的速度大小继续移动。

      现在,告诉你线段的长度L,小球数量n,以及n个小球的初始位置,请你计算t秒之后,各个小球的位置。

【提示】

      因为所有小球的初始位置都为偶数,而且线段的长度为偶数,可以证明,不会有三个小球同时相撞,小球到达线段端点以及小球之间的碰撞时刻均为整数。

      同时也可以证明两个小球发生碰撞的位置一定是整数(但不一定是偶数)。

【输入格式】

      输入的第一行包含三个整数n, L, t,用空格分隔,分别表示小球的个数、线段长度和你需要计算t秒之后小球的位置。

      第二行包含n个整数a1, a2, …, an,用空格分隔,表示初始时刻n个小球的位置。

【输出格式】

      输出一行包含n个整数,用空格分隔,第i个整数代表初始时刻位于ai的小球,在t秒之后的位置。

【输入样例1】

3 10 5

4 6 8

【输出样例1】

7 9 9

【输入样例2】

10 22 30

14 12 16 6 10 2 8 20 18 4

【输出样例2】

6 6 8 2 4 0 4 12 10 2

#include<bits/stdc++.h>
using namespace std;

const int N=105;
pair<int,int> a[N];
int b[N],c[N];

int main()
{
	int n,L,t;
	cin>>n>>L>>t;
	for(int i=1;i<=n;i++){
		cin>>a[i].first;
		a[i].second=i;
		b[i]=a[i].first+t;
		b[i]=b[i]%(2*L);
		if(b[i]>L) {
			b[i]=2*L-b[i];
		}
	}
	sort(a+1,a+1+n);//所有小球从左往右数 
	sort(b+1,b+1+n);
	for(int i=1;i<=n;i++)
	{
		c[a[i].second]=i;//第几个输入的 
	}
	for(int i=1;i<=n;i++)
	{
		cout<<b[c[i]]<<" ";
	}
	return 0;
}

三元组最短距离

【问题描述】

定义三元组(a,b,c)(a,b,c均为整数)的距离D = ∣ a − b ∣ + ∣ b − c ∣ + ∣ c − a ∣ 。给定3个非空整数集合S1,S2和S3,按升序分别存储在3个数组中。请设计一种尽可能高效的算法,计算并输出所有可能的三元组(a,b,c)(a ∈ S1 , b ∈ S2 , c ∈ S3)中的最小距离。 

例如,S1={-1,0,9},S2={-25,-10,10,11},S3={2,9,17,30,41},则最小距离为2,相应的三元组为(9,10,9)。要求:

(1)给出算法的基本设计思想。 //以注释形式写在程序中

(2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。 

(3)说明你所设计算法的时间复杂度和空间复杂度。//以注释形式写在程序中

【提示】

集合大小:1-10000

整数大小:1-1000000

【样例输入】

3 4 5
-1 0 9
-25 -10 10 11
2 9 17 30 41

【样例输出】

2

三元组最小距离_三元组最短距离_跨考上浙大的博客-CSDN博客

#include<bits/stdc++.h>
using  namespace std;
const int maxn=10010;
const int inf=0x7fffffff;
int a[maxn],b[maxn],c[maxn];
int main(){
	int m,n,l;
	cin>>m>>n>>l;
	for(int i=0;i<m;i++) cin>>a[i];
	for(int i=0;i<n;i++) cin>>b[i];
	for(int i=0;i<l;i++) cin>>c[i];
	int i=0,j=0,k=0;
	vector<int>v1,v2,v3;//保存三元组序列 
	int dis=inf;
	while(1){
		if(i==m || j==n || k==l) break;
		int temp=abs(a[i]-b[j])+abs(a[i]-c[k])+abs(b[j]-c[k]);
		if(temp<dis){
		    dis=temp;	
			v1.clear();v1.push_back(a[i]);
			v2.clear();v2.push_back(b[j]);
			v3.clear();v3.push_back(c[k]);
		}else if(temp==dis){ 
			v1.push_back(a[i]);
			v2.push_back(b[j]);
			v3.push_back(c[k]);
		} 
		if(a[i]<=b[j] && a[i]<=c[k]) i++;
		else if(b[j]<a[i] && b[j]<c[k]) j++;
		else k++;
	}
	cout<<dis<<endl; 
	/*for(int i=0;i<v1.size();i++){
		cout<<v1[i]<<" "<<v2[i]<<" "<<v3[i]<<endl;
	}*/
	return 0;
}  

3.

两个有序单链表的合并

【问题描述】两个不带头结点的有序单链表LA和LB的合并,请合并到LA表中再输出,LB表的空间全部释放。

【样例输入】

1 3 5 7 9 0

1 2 3 4 15 20 0

【样例输出】

1 2 3 4 5 7 9 15 20

【注意】0代表输入结束

两个有序单链表的合并(二路归并)_Wonder-King的博客-CSDN博客

#include<iostream>
using namespace std;

typedef struct LinkNode{
	int data;
	struct LinkNode *next;
}LinkNode;

void CreateListR(LinkNode *&L,int a[],int na)//尾插法
{
	L=new LinkNode;
	L->next=NULL;
	LinkNode *node=NULL;
	LinkNode *end=NULL;
	end=L;
	for(int i=0;i<na;i++)
	{
		node=new LinkNode;
		node->data=a[i];
		
		end->next=node;
		end=node;
		
	}
	end->next=NULL;
	
}
void Print(LinkNode *L)
{
	LinkNode *p=L;
	while(p->next!=NULL)
	{
		p=p->next;
		printf("%d ",p->data);
	}
} 
void MergeList(LinkNode *La,LinkNode *Lb,LinkNode *&Lc)
{
	LinkNode *pa=La->next,*pb=Lb->next,*pc,*q;
	Lc=pc=La;
	while(pa&&pb)
	{
		if(pa->data<pb->data)
		{
			pc->next=pa;
			pc=pc->next;
			pa=pa->next;
		}
		else if(pa->data>pb->data)
		{
			pc->next=pb;
			pc=pc->next;
			pb=pb->next;
		}else
		{
			pc->next=pa;
			pc=pc->next;
			pa=pa->next;
			q=pb->next;
			delete pb;
			pb=q;
		}	
	}
	pc->next=pa?pa:pb;//如果pa非空,就将pa接在Lc后面
}
 
int main()
{
	int a[]={1,7,13};
	int b[]={2,4,6,8,10,11};
	LinkNode *La,*Lb,*Lc;
	int na=3,nb=6;
	CreateListR(La,a,na);
	Print(La);	
	CreateListR(Lb,b,nb);
	cout<<endl;
	Print(Lb);
	MergeList(La,Lb,Lc);
	cout<<endl;
	Print(Lc);	
	return 0;		
}

合并两个有序单链表_合并两个有序的单链表_yuki_1209的博客-CSDN博客

两个有序单链表的合并_合并两个有序单链表_ibbdw的博客-CSDN博客

头插法创建,输入创建,二合一

#include<bits/stdc++.h>
using namespace std;
typedef struct node{
	int data;
	struct node *next;
}node,*pnode;
void create(int a[],int n,pnode &l)
{
	l=new node;
	pnode pre,tail=l;
	for(int i=0;i<n;i++)
	{
		pre=new node;
		pre->data=a[i];
		pre->next=NULL;
		tail->next=pre;

		tail=tail->next;
	}
}
void show(pnode l)
{
	pnode p=l->next;
	while(p)
	{
		cout<<p->data<<" ";
		p=p->next;
	}

}
void Merge(pnode &a,pnode &b)
{
    pnode pa,pb,ta,tb;
    pnode q;                  // 1 3 5 7 9
                              // 2 t  6 8
    pa=a->next;
    pb=b->next;
    ta=a;
    tb=b;
    while(pa&&pb)
    {

        if(pa->data > pb->data)//插在pa和ta之间
        {
            q=pb->next;
            pb->next=pa;
            ta->next=pb;
            pb=q;
            ta=ta->next;
        }
        else if(pa->data < pb->data){
            ta=pa;
            pa=pa->next;
        }
        else
        { pb=pb->next;
          tb=tb->next;
        }
    }
    if(pb)
    {
        pa->next=pb;
    }

}
int main()
{
	int a[10];
	int b[10];
	int x,na=0,nb=0;
	while(cin>>x&&x)
    {
        a[na++]=x;
    }
    while(cin>>x&&x)
    {
        b[nb++]=x;
    }
	pnode la,lb;
	create(a,na,la);
	create(b,nb,lb);
	show(la);
	cout<<endl;
	show(lb);
	cout<<endl;
	Merge(la,lb);
	show(la);
}

4.

单链表数据排序

【问题描述】用单链表存储数据,实现对结点整体的从小到大的排序。

【注意】可采用翻转课堂上讲解的插入、冒泡排序中的一种,或者采用选择排序。每组成员一共需要实现其中的两种排序:插入和选择排序、或者冒泡和选择排序。

【输入形式】待排序的数据,以0作为结束。

【输出形式】排序后的数据

【样例输入】2 4 3 1 5 0

【样例输出】1 2 3 4 5

法一:data只有一个的情况,练手不推荐

//4. 单链表数据排序
#include<iostream>
#include<cstdlib>
using namespace std;
struct Node{
	int data;
	Node *next;
};
void create(Node *head)
{
	Node *rear=head;
	

	int x;
	while(1)
	{
		cin>>x;
		if(x!=0)
		{
			Node *newp=(Node*)malloc(sizeof(Node));
				newp->next=NULL; 
			newp->data=x;
			rear->next=newp;
			rear=rear->next;
		}
		else break;
	}
}
void  BubbleSort(struct Node* list)
{
    for (struct Node* first = list->next; first != NULL; first = first->next)
    {
        for (struct Node* second = list->next; second != NULL; second = second->next)
        {
            if (second->next != NULL)
            {
                if (second->data> second->next->data) 
                {
                    int  temp = second->data;
                    second->data = second->next->data;
                    second->next->data = temp;
                }
            }
        }
    }
}
void travel(Node *head)
{
	Node *p=head->next;
	while(p)
	{
		cout<<p->data<<" ";
		p=p->next;
	}
}
int main()
{
	Node *head=(Node*)malloc(sizeof(Node));
	create(head);
	BubbleSort(head);
	travel(head);
	return 0;
}



f对链表进行插入排序_链表插入排序_程序员大航子的博客-CSDN博客

法二:对链进行操作

数据结构--链表的排序详解_结构体链表排序_Ouyang_Lianjun的博客-CSDN博客

5.

多项式相加

【问题描述】编写一个程序用单链表存储多项式,并实现两个一元多项式A与B相加的函数。A,B刚开始是无序的,A与B之和按降序排列。例如:
                        多项式A:  1.2X^0  2.5X^1  3.2X^3  -2.5X^5
                        多项式B:  -1.2X^0  2.5X^1  3.2X^3   2.5X^5   5.4X^10
                        多项式A与B之和:5.4X^10  6.4X^3  5X^1
【输入形式】第一行第一个数据n代表多项式的总项数,后面的2*n个数据,每一对代表对应的某一项的系数和指数,第二行类似,第三行的数据x要查询第几项
【输出形式】多项式中某一项的系数与指数,系数保留一位小数

【输入样例】
4 1.2 0 2.5 1 3.2 3 -2.5 5
5 -1.2 0 2.5 1 3.2 3 2.5 5 5.4 10
2

【输出样例】

6.4 3

【样例说明】
第一个多项式的系数与指数对,以空格隔开
第二个多项式的系数与指数对,以空格隔开
输出第2项的系数与指数,系数与指数间用空格隔开,系数保留一位小数

【评分标准】必须用链表实现

多项式相加求和(C语言链表版)_多项式求和c语言_大‭‭麒麟儿的博客-CSDN博客

多项式相加(C语言版 链表版+数组版)_谛凌的博客-CSDN博客

#include<stdio.h>
#include<stdlib.h>
#include<bits/stdc++.h>
using namespace std;
typedef struct PolyNode
{
	int coef;
	int expon;
	struct PolyNode* Link;
}PolyNode;//结构体构建多项式项的架构
PolyNode* Init_Polynomial()  //初始化第一个多项式
{
	PolyNode* header = (PolyNode*)malloc(sizeof(PolyNode));
	//PolyNode *header=new PolyNode'
	PolyNode* pRear = header;
	header->coef = 0;
	header->expon = 0;
	header->Link = NULL;
	int coef = 0;
	int expon = 0;
	while (1)
	{
	   cin>>coef;
		if (coef == 0)
		{
			break;
		}
		cin>>expon;
		PolyNode* NewNode = (PolyNode*)malloc(sizeof(PolyNode));
		NewNode->coef = coef;
		NewNode->expon = expon;
		NewNode->Link = NULL;
		pRear->Link = NewNode;
		pRear = NewNode;
	}
	return header;
}

void travel(PolyNode* header)
{
	struct PolyNode* pCurrent =(PolyNode*) malloc(sizeof(PolyNode));
	pCurrent = header->Link;
	while (pCurrent != NULL)
	{
		printf("%d %d ", pCurrent->coef, pCurrent->expon);
		pCurrent = pCurrent->Link;
	}
}
int Compare_Expon(int a, int b)
{
	if (a > b)
		return 1;
	if (a == b)
		return 0;
	if (a < b)
		return -1;
 
}
PolyNode* Add(PolyNode* P1, PolyNode* P2)
{
	int sum = 0, e = 0;
	 PolyNode* Front =(PolyNode*) malloc(sizeof(PolyNode));
	 PolyNode* Rear = Front;
	Front->coef = 0;
	Front->expon = 0;
	Front->Link = NULL;
	while (P1 && P2)
	{
		PolyNode* NewNode =(PolyNode*) malloc(sizeof(PolyNode));
		e = Compare_Expon(P1->expon, P2->expon);
		switch (e)
		{
		case 1:
			NewNode->coef = P1->coef;
			NewNode->expon = P1->expon;
			NewNode->Link = NULL;
			Rear->Link = NewNode;
			Rear = NewNode;
			P1 = P1->Link;
			break;
		case 0:
			sum = P1->coef + P2->coef;
			NewNode->coef = sum;
			NewNode->expon = P1->expon;
			NewNode->Link = NULL;
			Rear->Link = NewNode;
			Rear = NewNode;
			P1 = P1->Link;
			P2 = P2->Link;
			break;
		case -1:
			NewNode->coef = P2->coef;
			NewNode->expon = P2->expon;
			NewNode->Link = NULL;
			Rear->Link = NewNode;
			Rear = NewNode;
			P2 = P2->Link;
			break;
		}
		
	}
	if (P1 != NULL)
	{
		PolyNode* NewNode1 =(PolyNode*) malloc(sizeof(PolyNode));
		NewNode1 = P1;
		Rear->Link = NewNode1;
		Rear = NewNode1;
		P1 = P1->Link;
 
	}
	if (P2 != NULL)
	{
	   PolyNode* NewNode2 = (PolyNode*)malloc(sizeof(PolyNode));
		NewNode2 = P2;
		Rear->Link = NewNode2;
		Rear = NewNode2;
		P2 = P2->Link;
 
	}
	return Front;
}
int main()
{
	printf("请输入第一个多项式的各项:");
	 PolyNode* header1 = Init_Polynomial();
	printf("请输入第二个多项式的各项:");
	PolyNode* header2 = Init_Polynomial();
	printf("第一个多项式的各项为:");
	travel(header1);
	printf("\n第二个多项式的各项为:");
	travel(header2);
	 PolyNode* a = header1->Link;
	 PolyNode* b = header2->Link;
	PolyNode* Front = Add(a,b);
	printf("\n两个多项式相加的结果为:");
	travel(Front);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值