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 分)
小唐正在学习数据结构。他尝试应用数据结构理论处理数据。最近,他接到一个任务,要求维护一个动态数据表,并支持如下操作:
-
插入操作(I):从表的一端插入一个整数。
-
删除操作(D):从表的另一端删除一个整数。
-
取反操作(R):把当前表中的所有整数都变成相反数。
-
取最大值操作(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();
}
}