北邮2019机试题(未进行oj测试)

计算机

Problem A 二进制
题目描述:
输入 32 位的二进制 01 串,输出这个数+1 和+3 后的 32 位二进制串
输入描述:
先输入 T,表示输入的组数
然后输入 T 行二进制串
输出描述:
输出+1 和+3 后的二进制串
输入样例:
2
00000000000000000000000000000000
00000000000000000000000000000001
输出样例:
00000000000000000000000000000001
00000000000000000000000000000011
00000000000000000000000000000010
00000000000000000000000000000100

#include <bits/stdc++.h>
#define max 50000
using namespace std;
int main(){
	int n;
	while(scanf("%d",&n)!=EOF){
		for(int i=0;i<n;i++){
			char str[32];
			scanf("%s",str);
			//+1
			int c=1;
			for(int i=31;i>=0;i--){
				int tmp=str[i]-'0'+c;
				str[i]=tmp%2+'0';
				c=tmp/2;
			}
			printf("%s\n",str);
			c=1;
			for(int i=30;i>=0;i--){
				int tmp=str[i]-'0'+c;
				str[i]=tmp%2+'0';
				c=tmp/2;
			}
			printf("%s\n",str);
		}
			
	}
	return 0;
}

Problem 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 <bits/stdc++.h>
#define inf 0x7fffffff
using namespace std;
struct point{
	int data,dist;
	point(int data,int dist):data(data),dist(dist) {}
	bool operator < (const point &x) const{
		return dist>x.dist;
	}
};
int dis[100];
vector<int> graph[100];
void dijsktra(int s,int n){
	fill(dis+1,dis+n+1,inf);
	priority_queue<point> pq;
	dis[s]=0;
	pq.push(point(s,dis[s]));
	while(!pq.empty()){
		int cur=pq.top().data;
		pq.pop();
		for(int i=0;i<graph[cur].size();i++){
			int next=graph[cur][i];
			if(dis[next]>dis[cur]+1){
				dis[next]=dis[cur]+1;
				pq.push(point(next,dis[next]));
			}
		}
	}
}
int main(){
	int t,n,m;
	for(scanf("%d",&t);t--;){
		scanf("%d%d",&n,&m);
		memset(graph,0,sizeof(graph));
		for(int i=1;i<=n;i++){
			for(int j=0;j<2;j++){
				int x;
				scanf("%d",&x);
				if(x!=-1){
					graph[i].push_back(x);
					graph[x].push_back(i);
				}
			}
		}
//测试图建立正确与否 
//		for(int i=1;i<=n;i++){
//			printf("%d->",i);
//			for(int j=0;j<graph[i].size();j++)
//				printf("%d ",graph[i][j]);
//			printf("\n");
//		}
		for(int i=0;i<m;i++){
			int s,e;
			scanf("%d%d",&s,&e);
			dijsktra(s,n);
			//测试dis数组是否正确
//			for(int j=1;j<=n;j++)
//				printf("%d ",dis[j]);
			printf("%d\n",dis[e]);
		}
	} 
	return 0;
}

题目即求最近公共节点,开辟记录父节点的数组

#include <bits/stdc++.h>
using namespace std;
int main(){
	int t,n,m,tree[100],l,r,x,y;
	for(scanf("%d",&t);t--;){
		scanf("%d%d",&n,&m);
		tree[1]=-1;
		for(int i=1;i<=n;i++){
			scanf("%d%d",&l,&r);
			if(l!=-1) tree[l]=i;
			if(r!=-1) tree[r]=i;
		} 
		while(m--){
			stack<int> vx,vy;
			scanf("%d%d",&x,&y);
			while(tree[x]!=-1){
				vx.push(x);
				x=tree[x];
			} 
			while(tree[y]!=-1){
				vy.push(y);
				y=tree[y];
			}
			while(!vx.empty()&&!vy.empty()){
				if(vx.top()==vy.top()){
					vx.pop();
					vy.pop();
				}else{
					break;
				}
			}
			printf("%d\n",vx.size()+vy.size());
		}
	}
	return 0;
}

参考了大佬的代码,简化了代码。

Problem 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
只写了白天有重复边的情况

#include <bits/stdc++.h>
#define inf 0x7fffffff
using namespace std;
struct edge{
	int to,len;
	edge(int to,int len):to(to),len(len) {}
}; 
struct point{
	int data,dist;
	point(int data,int dist):data(data),dist(dist) {}
	bool operator < (const point &x) const{
		return dist>x.dist;
	}
};
int dis[100];
vector<edge> graph[100];
void dijsktra(){
	priority_queue<point> pq;
	dis[1]=0;
	pq.push(point(1,0));
	while(!pq.empty()){
		int cur=pq.top().data;
		pq.pop();
		for(int i=0;i<graph[cur].size();i++){
			edge next=graph[cur][i];
			if(dis[next.to]>dis[cur]+next.len){
				dis[next.to]=dis[cur]+next.len;
				pq.push(point(next.to,dis[next.to]));
			}
		}
	}
}
int main(){
	int t,n,m,k;
	for(scanf("%d",&t);t--;){
		scanf("%d%d%d",&n,&m,&k);
		fill(dis+1,dis+n+1,inf);
		memset(graph,0,sizeof(graph));
		while(m--){
				int x,y,len;
				scanf("%d%d%d",&x,&y,&len);
				bool flag=true;
				for(int i=0;i<graph[x].size();i++){
					if(graph[x][i].to==y&&graph[x][i].len>len){
						graph[x][i].len=len;
						graph[i][x].len=len;
						flag=false;
					}
				}
				if(flag){
					graph[y].push_back(edge(x,len));
					graph[x].push_back(edge(y,len));
				}
		}
		while(k--){
			int num;
			scanf("%d",&num);
		}
		dijsktra();
		printf("%d\n",dis[n]);
		 
		for(int i=0;i<m;i++){
			int s,e;
			scanf("%d%d",&s,&e);
			for(int j=1;j<=n;j++)
				printf("%d ",dis[j]);
			printf("%d\n",dis[e]);
		}
	} 
	return 0;
}


Problem_A(牙膏问题):
4只牙膏比较价格,返回最便宜的牙膏
输入:
第一行输入T,表示数据的组数
第二行输入a b c d 表示4只牙膏的价格
2
2 3 5 2
3 8 7 4
输出:
2
3

#include <bits/stdc++.h>
using namespace std;
int main(){
	int t,num[4];
	for(scanf("%d",&t);t--;){
		for(int i=0;i<4;i++)
			scanf("%d",&num[i]);
		sort(num,num+4);
		printf("%d\n",num[0]);
	}
	return 0;
}

Problem_B(闰年问题):
统计连个年份间能被4整除且不能被100整除的普通闰年和能被400整除的世纪闰年的年数
输入:
第一行输入T,表示数据的组数
之后输入T组数据,每组输入x y代表始末年份(y<x)
2
2999 3019
1999 2019
输出:
4
5

#include <bits/stdc++.h>
using namespace std;
bool isrun(int y){
	return ((y%4==0&&y%100!=0)||y%400==0)?true:false;
}
int main(){
	int t,num[4];
	for(scanf("%d",&t);t--;){
		int x,y,cnt=0;
		scanf("%d%d",&x,&y);
		for(int i=x;i<=y;i++){
			if(isrun(i)) cnt++;
		}
		printf("%d\n",cnt);
	}
	return 0;
}

Problem_C(链表操作):
一个出值为 1,2,3,4,…,n的n(0<n<=50)个节点的顺序链表,有以下3种操作方式:
1 移除节点值为x的节点
2 翻转链表,对调整个链表的顺序
3 查询链表值为x的节点所指的下一个节点的值
输入:
第一行输入T,表示数据的组数
每组第一行输入 n (表示节点数目) m (表示操作数目)
接下来m行分别输入 ope (操作方式) x (操作的节点值,操作方式为2时不会输入该值)
1
6 6
3 6
1 2
3 1
2
1 5
3 6
输出:
输出操作为3查询时,所查节点所指的下一个节点值,若没有查到或查到的节点为表尾 (没有下一节点),输出"NONE"
NONE
3
4
对vector翻转:reverse(v.begin(),v.end())
删除vector的i位:v.erase(v.begin()+i)

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

int main(){
	int t;
	vector<int> v;
	for(scanf("%d",&t);t--;){
		v.clear();
		int n,m,op,num;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
			v.push_back(i);
		while(m--){
			scanf("%d",&op);
			if(op==2){
				reverse(v.begin(),v.end());
			}else{
				bool flag=false;
				scanf("%d",&num);
					for(int i=0;i<v.size();i++)
						if(v[i]==num){
							if(op==1){
								v.erase(v.begin()+i);
								break;
							}
							else if(i<v.size()-1){
								printf("%d\n",v[i+1]);
								flag=true;
								break;	
							}
						}
					if(op==3&&!flag) printf("NONE\n");
			}
			for(int i=0;i<v.size();i++)
				printf("%d ",v[i]);
			printf("\n");	
		}
	}
	return 0;
}

Problem_D(网络连接prim):
有一个保证能联通的计算机网络(连通图),
Aij表示i计算机联通到j计算机的开销,
保证 :Aii = 0 , Aij = Aji ,Aij <= 100;
输入:
第一行输入T (T=1),表示数据的组数
每组第一行输入N (0 < N <= 50),表示网络内计算机的数目
然后n行输入Ai0 - Ai n-1
1
6
0 1 4 3 7 3
1 0 2 5 1 8
4 2 0 3 9 2
3 5 3 0 1 4
7 1 9 1 0 3
3 8 2 4 3 0
输出:
返回连通这个计算机网络需要的最小开销
7
其实就是求最小生成树

#include <bits/stdc++.h>
using namespace std;
struct edge{
	int cost;
	int x,y;
	edge(int cost,int x,int y):cost(cost),x(x),y(y) {}
	bool operator < (const edge &x) const{
		return cost>x.cost;
	}
};
int tree[51];
int gettree(int x){
	if(x!=tree[x]) tree[x]=gettree(tree[x]);
	return tree[x];
}
bool nounion(int x,int y){
	x=gettree(x);
	y=gettree(y);
	if(x!=y){
		tree[x]=y;
		return true;
	}
	return false;
}
int main(){
	int t,n,num[51][51];
	for(scanf("%d",&t);t--;){
		scanf("%d",&n);
		priority_queue<edge> pq;
		for(int i=0;i<n;i++){
			tree[i]=i;
		}
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++){
				scanf("%d",&num[i][j]);
				if(j>i){
					pq.push(edge(num[i][j],i,j));
					pq.push(edge(num[i][j],j,i));
				}
			}
		int ans=0; 
		while(!pq.empty()){
			edge e=pq.top();
			pq.pop();
			if(nounion(e.x,e.y)){
				ans+=e.cost;
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 一本通 OJ 题库的测试据,通常是用来验证提交的代码在各种情况下的正确性。测试据可以分为两种类型,手动和自动。 手动测试据是由题目的出题人根据题意和据范围设计的一组据,用来检测程序的正确性和运行效率。手动测试据的优点是能够涵盖各种情况,但缺点是量相对较少,不足以覆盖所有可能的情况。 自动测试据是由程序自动生成的一组据,可以生成大量的据以检测程序的健壮性和效率。自动测试据的优点是量大且可以自动生成,但缺点是可能无法覆盖某些特殊情况,导致漏洞。 对于提交的代码,一本通 OJ 题库会对其进行编译和运行,然后与测试进行比较,判断代码的正确性和效率。如果代码通过了测试据,就会被判定为正确,否则会被判定为错误,并给出具体的错误信息,供用户进行调试和改进。 综上所述,一本通 OJ 题库的测试据是一个重要的组成部分,它可以帮助用户测试代码的正确性和运行效率,提高用户的编程技能,同时也可以帮助出题人设计更好的题目,并保证题目的质量和难度。 ### 回答2: 一本通 oj题库是一个在线的程序设计竞赛平台,提供了丰富的编程题目和测试据。测试据是用于对程序进行测评的输入输出据集合。在题目描述中,会对问题进行详细的解释和要求,并提供多组测试据作为样例,让程序员运行他们的代码,并得到程序的输出结果。 测试据通常包括正向测试据和反向测试据。正向测试据是指符合题目条件的测试据,覆盖了大多情况,测试程序是否正确;而反向测试据则是用于测试程序是否能够正确处理异常情况。 在使用一本通 oj题库时,程序员不仅需要通过编写算法和程序的方式解决问题,还需要通过分析测试据来判断自己的代码是否正确。而一本通 oj题库的丰富据集合为程序员提供了充足的测试据,帮助程序员准确地检测代码中存在的漏洞和错误。 总之,一本通 oj题库提供了全面的测试据来测试程序员的代码是否满足题目描述和要求,是程序员进行程序设计竞赛、算法练习和编程学习的良好平台。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值