机试练习Day1-2019真题

Problem A:32位二进制数的加法

题目:

第一行:输入测试数据组数N,第二行开始:输入N行32位的二进制数。
对其进行+1,+3后,输出N*2行计算结果。

样例:

在这里插入图片描述

代码:

学习参考原址

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

int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		string str;
		cin>>str;
		
		//找到最低位 +1
		int idx=str.size()-1; 
		while(str[idx]=='1')
		{
			str[idx--]='0'; 
		}
		str[idx]='1'; 
		cout<<str<<endl;
		
		//找到最低位 +1
		idx=str.size()-1;
		while(str[idx]=='1')
		{
			str[idx--]='0';
		}
		str[idx]='1';
		
		找到最低位 +1
		idx=str.size()-1;
		while(str[idx]=='1')
		{
			str[idx--]='0';
		}
		str[idx]='1';
		
		cout<<str<<endl;
	}
	return 0;
 } 

运行:

在这里插入图片描述

复盘:

万能头文件:

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

字符串:

		string str;
		cin>>str;

在这里插入图片描述
每次加1:

		idx=str.size()-1;
		while(str[idx]=='1')
		{
			str[idx]='0'; 
			idx=idx-1;
		}
		str[idx]='1';

Problem B:二叉树结点间的最短距离

题目:

第一行输入测试数据组数T,第二行输入二叉树的结点个数n和要查询的数据组数m,第三行开始输入n行,每行两个数,代表每个结点的孩子编号(根节点为1,没有孩子结点为-1),第3+n+1行开始输入m行,每行两个数,代表要查询的两个结点。
输出m行,代表m组结点间的最短距离。

样例:

在这里插入图片描述

代码:

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

int father[505];//父节点 
int len[505];//当前深度 
int dis;//距离 
void findRoot(int a,int b)
{
	if(a==b)
	{
		return ;
	} 
	dis++;
	if(len[a]>=len[b])
	{
		findRoot(father[a],b);
	}
	else if(len[a]<len[b])
	{
		findRoot(a,father[b]);
	}
	return ;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		//memset函数是内存赋值函数,用来给某一块内存空间进行赋值的
		memset(father,0,sizeof(father));
		memset(len,0,sizeof(len));
		father[1]=-1;//根节点,初始就存在
		len[1]=1;//根节点深度初始为1 
		int n,k;
		cin>>n>>k;
		for(int i=1;i<=n;i++)
		{
			int a,b;
			cin>>a>>b;
			//若输入为-1表示子节点不存在 
			if(a!=-1)
			{
				father[a]=i;
				len[a]=len[i]+1;
			}
			if(b!=-1)
			{
				father[b]=i;
				len[b]=len[i]+1;
			}
		}
		for(int i=0;i<k;i++)
		{
			int a,b;
			cin>>a>>b;//查询的两个节点
			dis=0;
			findRoot(a,b);
			cout<<dis<<endl;	
		} 
	}
	return 0;
 } 

运行:

在这里插入图片描述

复盘:

和Problem A一样,第一个数值都是测试数据的组数。
两个不同结点间的距离(将其称为左结点和右结点),那么可以通过找两者的父节点、父节点的父节点…直到结点重合,这是一个递归的过程。

void findRoot(int a,int b)
{
	if(a==b)
	{
		return ;
	} 
	dis++;
	if(len[a]>=len[b])
	{
		findRoot(father[a],b);
	}
	else if(len[a]<len[b])
	{
		findRoot(a,father[b]);
	}
	return ;
}

Problem C:两个城市间的最短路径

题目:

背景:晚上因为会关掉某些路,所以从城市1到城市n白天和晚上的最短路径可能不同。
第一行输入测试数据组数T,第二行输入城市数n,路径数m,晚上关闭的路径数k。
接下来n行,输入n条边的两个端点及长度。最后一行k个数,表示晚上关闭的线路序号。
输出两行,分别代表白天和黑夜从城市1到城市n的最短路径长度。

样例:

在这里插入图片描述

代码:

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

const int maxn=100000;//表示不可达 
int t[55][55];
struct E{
	int a,b;//道路的两个端点 
	int cost;//道路的长度 
}Edge[505];
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n,m,k;
		int res1,res2;//存储两次结果 
		cin>>n>>m>>k;
		//初始化所有城市不可达 
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				t[i][j]=maxn;
			}
		}
		//输入边 
		for(int i=1;i<=m;i++)
		{
			int a,b,cost;
			cin>>a>>b>>cost;
			Edge[i].a=a;
			Edge[i].b=b;
			Edge[i].cost=cost;
		}
		//将权值存入邻接矩阵 
		for(int i=1;i<=m;i++)
		{
			int a=Edge[i].a;
			int b=Edge[i].b;
			int cost=Edge[i].cost;
			//因为有重边,所以要选择最小的那条边放入 
			if(t[a][b]>cost)
			{
				t[a][b]=cost;
				t[b][a]=cost;
			}
		}
		//Floyed算法 
		for(int l=1;l<=n;l++)
		{
			for(int i=1;i<=n;i++)
			{
				for(int j=1;j<=n;j++)
				{
					if(t[i][l]+t[l][j]<t[i][j])
					{
						t[i][j]=t[i][l]+t[l][j];
					}
				}
			}
		}
		res1=t[1][n];
		
		//第二次初始化所有城市不可达 
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				t[i][j]=maxn;
			}
		}
		//输入夜晚要封路的边
		for(int i=0;i<k;i++)
		{
			int idx;//要封第idx条边 
			cin>>idx;
			Edge[idx].cost=maxn;
		}
		//将权值存入邻接矩阵 
		for(int i=1;i<=m;i++)
		{
			int a=Edge[i].a;
			int b=Edge[i].b;
			int cost=Edge[i].cost;
			//因为有重边,所以要选择最小的那条边放入 
			if(t[a][b]>cost)
			{
				t[a][b]=cost;
				t[b][a]=cost;
			}
		}
		//Floyed算法 
		for(int l=1;l<=n;l++)
		{
			for(int i=1;i<=n;i++)
			{
				for(int j=1;j<=n;j++)
				{
					if(t[i][l]+t[l][j]<t[i][j])
					{
						t[i][j]=t[i][l]+t[l][j];
					}
				}
			}
		}
		res2=t[1][n];
		cout<<res1<<endl;
		cout<<res2<<endl;
	}
	return 0;
}

运行:

在这里插入图片描述

复盘:

在定义边的时候采用了结构体:

struct E{
	int a,b;//道路的两个端点 
	int cost;//道路的长度 
}Edge[505];

整体复盘

  • 二进制的加法,手算的时候记得过程,但是写成代码刚开始就很慌乱。
  • 11111111111111111111111111111111的加法要另外写,这个根本就忘记了,后来看大家分享才发现这个坑。
  • 计算二叉树两个结点间的距离,手算是会的,但是写成代码就要考虑考虑计算机的计算过程了。
  • 构建二叉树时也有点慌乱。
  • 图论中,构建边,通常会使用结构体这件事情也忘记了。
  • Floyed算法就更不用说了,一干二净。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只天蝎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值