2019北邮计算机机试

注意:所有代码均是根据题目描述进行了本地测试,没有在北邮oj上测试,不保证一定能AC。

点击链接查看历年机试题目汇总。

A二进制

题目描述

32位二进制数X,对其进行X+1,X+3 操作,并输出。注意不能忽略前导0

输入
第一行,一个整数T,代表测试数据组数。
接着T行,输入32为二进制数

输出
对每组测试数据,输出两行,第一行为X+1,第二行为X+3.

样例输入

2
00000000000000000000000000000000
00000000000000000000000000000001

样例输出

00000000000000000000000000000001
00000000000000000000000000000011
00000000000000000000000000000010
00000000000000000000000000000100

解析

二进制加1就是对最低位加1,然后处理进位。
二进制加3就是在加1的基础上再加2,即对倒数第二位加1,处理进位。  

#include <iostream>
#include <cstring>
#include <string>
using namespace std; 

void add(int begin,int end,char a[]) 
{
	for(int i=begin;i>=0;i--)
	{
		if(a[i]=='0') 
			{
				a[i]='1';
				break; 
			}
			else
			{
				a[i]='0';
			}
	}
	cout<<a<<endl;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		char a[32];
		cin>>a;
		add(31,0,a);
		add(30,0,a); 
	}
	return 0;
}

B 二叉树

题目描述

对二叉树,计算任意两个结点的最短路径长度。

输入
第一行输入测试数据组数T
第二行输入n,m 。n代表结点的个数,m代表要查询的数据组数
接下来n行,每行输入两个数,代表1~n结点的孩子结点,如果没有孩子结点则输入-1.根节点为1.
接下来m行,每行输入两个数,代表要查询的两个结点

输出
每组测试数据输出m行,代表查询的两个结点之间的最短路径长度

样例输入

1
8 4
2 3
4 5
6 -1
-1 -1
-1 7
-1 -1
8 -1
- 1 -1
1 6
4 6
4 5
8 1

样例输出

2
4
2
4


解析

用一个数组记录节点的父节点,求出两节点的深度,
先统一到相同深度,再同时向上走,直到相同。

#include <iostream>
using namespace std;
int depth(int t[],int v)
{
	if(t[v]==0) return 0;
	else return depth(t,t[v])+1;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
		{
			int n,m,f[100],d[100];
			f[1]=0;
			cin>>n>>m;
			int x,y;
			for(int i=1; i<=n; i++)
				{
					cin>>x>>y;
					if(x!=-1) f[x]=i;
					if(y!=-1) f[y]=i;
					d[x]=depth(f,x);
					d[y]=depth(f,y);
				}
			while(m--)
				{
					cin>>x>>y;
					int count=0;
					int d1=d[x],d2=d[y];
					while(d1!=d2)
						{
							count++;
							if(d1>d2)
								{
									d1--;
									x=f[x];
								}
							else
								{
									d2--;
									y=f[y];
								}
						}
					while(x!=y)
						{
							count+=2;
							x=f[x];
							y=f[y];
						}
					cout<<count<<endl;
				}
		}
	return 0;
}

C 中序遍历树

题目描述

在白天和黑夜要从城市1到城市n,黑夜会关掉若干条线路,分别寻找城市1到城市n的在白天和黑夜的最短路径。

输入
第一行数据组数T
第二行输入n,m,k. n代表城市数,m代表路径数,k代表夜间关闭的路径数
接下来m行,每行输入三个数x,y,val,代表城市x和城市y之间连通的距离为val
最后一行k个数,代表晚上关闭的线路序号(线路序号指的是1~m)
感谢补充:不保证无重边,这是考试时,后来补发的公告,所以这题a出的人很少也有这个原因

输出
每组数据输出两行,分别代表白天和黑夜,城市1到n的最短路径

样例输入

1
4 4 1
1 2 1
2 3 1
3 4 1
1 4 1
4

样例输出

1
3


解析

这道题主要是要考虑有重边的情况,先用一个vector数组保存路径及边,
然后再分白天和黑夜讨论。 

#include <iostream>
#include <vector>
#include <algorithm>
#define INF 0x3fffffff
using namespace std;
int n,m,k;
int G[1001][1001];
struct edge
{
	int val;
	int d;
	int f;
	edge(int from,int to,int v)
	{
		f=from;
		d=to;
		val=v;
	}
};
int floyd()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			for(int k=1;k<=n;k++)
			{
				if(G[i][k]!=INF&&G[k][j]!=INF&&G[i][k]+G[k][j]<G[i][j])
				G[i][j]=G[i][k]+G[k][j];
			}
		}
	}
	return G[1][n];
}
/*
//dijkstra算法 
int d[1001],vis[1001];
int dijkstra()
{
	fill(d,d+1001,INF);
	fill(vis,vis+1001,0);
	d[1]=0;
	for(int i=0;i<n;i++)
	{
		int u=-1,min=INF;
		for(int j=1;j<=n;j++)
		{
			if(!vis[j]&&d[j]<min)
			{
				u=j;
				min=d[j];
			}
		}
		if(u!=-1) 
		{
			vis[u]=1;
		}
		for(int j=1;j<=n;j++)
		{
			if(!vis[j]&&G[u][j]!=INF&&d[u]+G[u][j]<d[j])
			d[j]=G[u][j]+d[u];
		}
	}
	return d[n];
}
*/
vector<edge> E;
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		E.clear();
		fill(G[0],G[0]+1001*1001,INF);
		int x,y,val,close[1001]={0};
		cin>>n>>m>>k;
		for(int i=1;i<=m;i++)
		{
			cin>>x>>y>>val;
			E.push_back(edge(x,y,val));
		}
		for(int i=0;i<k;i++) 
		{
			int t;
			cin>>t;
			close[t]=1; //哈希 
		}
		for(unsigned int i=0;i<E.size();i++)
		{
				G[E[i].f][E[i].d]=G[E[i].d][E[i].f]=min(E[i].val,G[E[i].f][E[i].d]);	
		}
		cout<<floyd()<<endl;
		//cout<<dijkstra()<<endl;
		fill(G[0],G[0]+1001*1001,INF);
		//黑夜 
		for(unsigned int i=0;i<E.size();i++)
		{
			if(close[i+1]==0)
			{
				G[E[i].f][E[i].d]=G[E[i].d][E[i].f]=min(E[i].val,G[E[i].f][E[i].d]);
			}
		}
		cout<<floyd()<<endl; 
		//cout<<dijkstra()<<endl;
	}
	return 0;
}

据说这道题现场没有人做出来,很难,在网上我连题目都没找到。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值