0
点赞
收藏
分享

微信扫一扫

2021-06-15

小飞侠熙熙 2022-02-27 阅读 39

7-1 高精度数加法 (100 分)

高精度数是指大大超出了标准数据类型能表示的范围的数,例如10000位整数。很多计算问题的结果都很大,因此,高精度数极其重要。

一般使用一个数组来存储高精度数的所有数位,数组中的每个元素存储该高精度数的1位数字或多位数字。 请尝试计算:N个高精度数的加和。这个任务对于在学习数据结构的你来说应该是小菜一碟。 。

输入格式:

第1行,1个整数N,表示高精度整数的个数,(1≤N≤10000)。

第2至N+1行,每行1个高精度整数x, x最多100位。

输出格式:

1行,1个高精度整数,表示输入的N个高精度数的加和。

输入样例:

在这里给出一组输入。例如:

3
12345678910
12345678910
12345678910

输出样例:

在这里给出相应的输出。例如:

37037036730
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a[200];
int b[200];
char s[200];
int jin=0;
int change(char *p,int *q){
int j=strlen(p)-1;
int m=j;
	for(int k=1;j>=0;j--,k++)
	   q[k]=p[j]-'0';
return m+1;	   	
}
int main(){
	int n;
	cin>>n;
	scanf("%s",s);
	int maxn=change(s,a);
    for(int i=2;i<=n;i++)	
	{
	jin=0;	
	scanf("%s",s);
	memset(b,0,sizeof(b));
	int lb=change(s,b);
	if (lb>maxn)
	maxn=lb;
	for(int i=1;i<=maxn;i++)
	  {
	  	int flag=jin;
	    jin=(a[i]+b[i]+flag)/10;
		a[i]=(a[i]+b[i]+flag)%10;
			
	  }
	if(jin!=0)  
	{
	int nt=jin;	
	while(nt!=0)
	{
	a[++maxn]=nt%10;
	nt=nt/10;
		}	
	}
	 }
	for(int i=maxn;i>=1;i--)
	cout<<a[i];
}

7-2 二叉树加权距离 (100 分)

二叉树结点间的一种加权距离定义为:上行方向的变数×3 +下行方向的边数×2 。上行方向是指由结点向根的方向,下行方向是指与由根向叶结点方向。 给定一棵二叉树T及两个结点u和v,试求u到v的加权距离。

输入格式:

第1行,1个整数N,表示二叉树的结点数,(1≤N≤100000)。

随后若干行,每行两个整数a和b,用空格分隔,表示结点a到结点b有一条边,a、b是结点的编号,1≤a、b≤N;根结点编号为1,边从根向叶结点方向。

最后1行,两个整数u和v,用空格分隔,表示所查询的两个结点的编号,1≤u、v≤N。

输出格式:

1行,1个整数,表示查询的加权距离。

输入样例:

在这里给出一组输入。例如:

5
1 2
2 3
1 4
4 5
3 4

输出样例:

在这里给出相应的输出。例如:

8
#include<iostream>
#include<vector>
#include<cstdio>
#define maxn 100000+10
using namespace std;
int dep[maxn];
int parent[maxn];
int aa[maxn][2];
void set_degree(int now){
	for(int i=0;i<=1;i++)
	{   
	    if(aa[now][i]!=0)
		{
		dep[aa[now][i]]=dep[now]+1;
		set_degree(aa[now][i]);
		}
	}
}
int main(){
int n;
cin>>n;
parent[1]=1;
for(int i=1;i<=n-1;i++)	
  {
  	int j,k;
  	cin>>j>>k;
  	if(aa[j][0]==0)
  	aa[j][0]=k;
  	else
  	aa[j][1]=k;
    parent[k]=j;	
	  }
set_degree(1);
int u,v;
cin>>u>>v;
int extra=0;
if(dep[u]>dep[v])	
{
 extra=3*(dep[u]-dep[v]);
 while(dep[u]!=dep[v])
 u=parent[u]; 	
	}
if(dep[u]<dep[v])	
{
 extra=2*(dep[v]-dep[u]);
 while(dep[u]!=dep[v])
 v=parent[v];   	
	}
int step=0;
while(u!=v)
{
  u=parent[u];
  v=parent[v];
  step++;	
}
cout<<step*5+extra;	
		
}

7-3 修轻轨 (100 分)

长春市有n个交通枢纽,计划在1号枢纽到n号枢纽之间修建一条轻轨。轻轨由多段隧道组成,候选隧道有m段。每段候选隧道只能由一个公司施工,施工天数对各家公司一致。有n家施工公司,每家公司同时最多只能修建一条候选隧道。所有公司可以同时开始施工。请评估:修建这条轻轨最少要多少天。。

输入格式:

第1行,两个整数n和m,用空格分隔,分别表示交通枢纽的数量和候选隧道的数量,1 ≤ n ≤ 100000,1 ≤ m ≤ 200000。

第2行到第m+1行,每行三个整数a、b、c,用空格分隔,表示枢纽a和枢纽b之间可以修建一条双向隧道,施工时间为c天,1 ≤ a, b ≤ n,1 ≤ c ≤ 1000000。

输出格式:

输出一行,包含一个整数,表示最少施工天数。

输入样例:

在这里给出一组输入。例如:

6 6
1 2 4
2 3 4
3 6 7
1 4 2
4 5 5
5 6 6

输出样例:

在这里给出相应的输出。例如:

6
#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 200000
using namespace std;
int k=0; 
int father[maxn];
typedef struct node
{
int from,to,dis;//结构体储存边 
}Edg;
Edg edge[maxn];

bool cmp(const Edg &a,const Edg &b)
{
	return a.dis<b.dis;
}
int find(int x)//找集体老大,并查集的一部分 
{
	if(father[x]!=x)
	return father[x]=find(father[x]);
	else return x;
}
void join(int x,int y)//加入团体,并查集的一部分 
{    
    int t1=find(x);
    int t2=find(y);
    if(t1==t2)
    return ;
    else
	father[t1]=t2;
}
int main()
{   
    int n,m,num=0;
	scanf("%d%d",&n,&m);//输入点数,边数 
	for(int i=1;i<=m;i++)
		scanf("%d %d %d",&edge[i].from,&edge[i].to,&edge[i].dis);//输入边的信息 
	for(int i=1;i<=n;i++) 
	father[i]=i;//自己最开始就是自己的老大 (初始化) 
	sort(edge+1,edge+1+m,cmp);//按权值排序 
	for(int i=1;i<=m;i++)//从小到大遍历 
	{ 
		if(find(edge[i].from)!=find(edge[i].to))//假如不在一个团体 
		{
			join(edge[i].from,edge[i].to);//加入 
			num=edge[i].dis;
			if(find(1)==find(n))
			break;
			}
		}
	cout<<num;
}

7-4 数据结构设计I (100 分)

小唐正在学习数据结构。他尝试应用数据结构理论处理数据。最近,他接到一个任务,要求维护一个动态数据表,并支持如下操作:

  1. 插入操作(I):从表的一端插入一个整数。

  2. 删除操作(D):从表的另一端删除一个整数。

  3. 取反操作(R):把当前表中的所有整数都变成相反数。

  4. 取最大值操作(M):取当前表中的最大值。

    如何高效实现这个动态数据结构呢?

输入格式:

第1行,包含1个整数M,代表操作的个数, 2≤M≤1000000。

第2到M+1行,每行包含1个操作。每个操作以一个字符开头,可以是I、D、R、M。如果是I操作,格式如下:I x, x代表插入的整数,-10000000≤x≤10000000。 。

输出格式:

若干行,每行1个整数,对应M操作的返回值。如果M和D操作时队列为空,忽略对应操作。

输入样例:

在这里给出一组输入。例如:

6
I 6
R
I 2
M
D
M

输出样例:

在这里给出相应的输出。例如:

2
2
#include<iostream>
#include<queue>
#include<set>
#include<cstdio>
#include<algorithm>
using namespace std;
queue<int> jk;
queue<int> jt;
multiset<int,greater<int> > sm;
multiset<int,greater<int> > im; 

int main(){	
	int m=0;
	scanf("%d",&m);
	getchar();
	int flag=0;
	char ch;
	int nm=0;
for(int i=1;i<=m;i++){
	scanf("%c",&ch); 
	if(ch=='I')
			{
			scanf("%d",&nm);
			if(flag%2==0){
				jk.push(nm);
				jt.push(-nm);	
				sm.insert(nm);
				im.insert(-nm);
			}else{
				jk.push(-nm);
				jt.push(nm);	
				sm.insert(-nm);
				im.insert(nm);	
			}
			}
	if(ch=='D')
			{
			if(jk.empty()!=1){
				auto qq = sm.find(jk.front());
				auto qb = im.find(jt.front());
 				jk.pop();
				jt.pop();
				sm.erase(qq);
 				im.erase(qb);
	    	}
		}
			
	if(ch=='R')	
		   flag++;	
	
    if(ch=='M')		
		{
				if(jk.empty()!=1){
				if(flag%2!=0){
					auto pp =im.begin();
					printf("%d\n",*pp);
				}else {
				    auto pq =sm.begin();
				    printf("%d\n",*pq);	
				}
			} 
				
	   }

	getchar();		
}
	
}
举报

相关推荐

0 条评论