BUPT2014网研院机试Java题解

题目搜集于各位前辈,侵删。

第一题

分数加法
题目描述

求(2|a-b|)+1)/2max(a,b),其中a和b均为正整数,结果请用最简分数表示。

输入格式

第一行为测试数据的组数T(1<=T<=400)。请注意,任意两组测试数据之间是相互独立的。
每组测试数据一行,包含两个整数a和b(2<=a,b<=20)。

输出格式

对于每组测试数据,在一行内输出结果,分子和分母用“/”隔开。

输入样例

2
2 4
3 2

输出样例

5/16
3/8

import java.util.Scanner;

public class i1401 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt();
		for(int t=0;t<T;t++) {
			int a = sc.nextInt();
			int b = sc.nextInt();
			int high = (int)(Math.pow(2, Math.abs(a-b))+1);
			int low = (int) Math.pow(2, Math.max(a, b)); 
			for(int i = 2;i<=high&&i<=low;i++) {
				if(high%i==0&&low%i==0) {
					high/=i;
					low/=i;
				}
			}
			System.out.println(high+"/"+low);
		}
		sc.close();
	}

}

第二题

最小堆
题目描述

给定一棵带权二叉树,请判断它是不是一个最小堆。
一棵二叉树是一个最小堆,当且仅当对于树上任意一个节点,它的权值都小于或等于以它为根的子树中的所有权值。

输入格式

输入数据第一行是一个整数T(1<=T<=100),表示测试数据的组数。
对于每组测试数据:
第一行是一个整数N(1<=N<=100),表示树的节点个数。
接下来一行包含N个正整数,第i个整数valuei(1<=valuei<=1000)表示编号i的点的权值。
接下来N-1行,每行两个整数u和v(1<=u,v<=N, u!=v),表示节点u是节点v的父节点。
测试数据保证给定的一定是一棵二叉树,并且节点1是树的根结点。

输出格式

对于每组测试数据,如果给定的树是一个最小堆则输出Yes,否则输出No。

输入样例

3
1
10
3
10 5 3
1 2
1 3
5
1 2 3 4 5
1 3
1 2
2 4
2 5

输出样例

Yes
No
Yes

import java.util.Scanner;

public class i1402 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt();
		for(int t=0;t<T;t++) {
			int n = sc.nextInt();
			int[] arr = new int[n+1];
			for(int i = 1;i<=n;i++) {
				arr[i] = sc.nextInt();
			}
			int flag = 0;
			for(int i = 1;i<n;i++) {
				int father = sc.nextInt();
				int son = sc.nextInt();
				if(arr[father]>arr[son]) {
					flag = 1;
					break;
					
				}
			}
			if(flag == 0) {
				System.out.println("Yes");
			}else {
				System.out.println("No");
			}
			
		}
		sc.close();
	}

}

第三题

进程管理
题目描述

在操作系统中,进程管理是非常重要的工作,每个进程都有唯一的进程标识(PID)。每个进程都可以启动子进程,此时我们称它为其子进程的父进程,除了PID为0的进程之外,每个进程有且只有一个父进程,在这个任务中,你需要实时维护操作系统运行中的三个基本操作:

FORK PID1 PID2:标识为PID1的进程启动了一个标识为PID2的子进程。
KILL PID:结束标识为PID的进程。请注意,与此同时所有PID的子进程也将同时结束。如果PID是不存在或已经结束的进程,则不做任何操作。
QUERY PID:查询标识为PID的进程是否仍然存在。
在初始状态下,系统只开启了PID为0的进程,并且在任何情况下该进程不会结束。

输入格式

输入的第一行是一个整数T(T<=50),表示输入的数据组数。
每组测试数据的第一行是一个整数N(1<=N<=100),表示操作的数量。
每下来N行,每行按照上面的描述给出每个操作,输入保证所有的进程的PID都不相同,且一个进程结束后不会被重新启动,所有PID都是[1,100]之间的整数。

输出格式

对于每次QUERY查询,如果进程存在,输出Yes,不存在则输出No

输入样例

2
5
FORK 0 1
QUERY 1
KILL 1
QUERY 1
QUERY 2
1
QUERY 0

输出样例

Yes
No
No
Yes

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class i1403 {

	static Process root = new Process(0);
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt();
		for(int t=0;t<T;t++) {
			int n = sc.nextInt();
			for(int i = 0;i<n;i++) {
				String op = sc.next();
				if(op.equals("FORK")) {
					int pid1 = sc.nextInt();
					int pid2 = sc.nextInt();
					Process father = search(root,pid1);
					Process son = new Process(pid2);
					father.son.add(son);
				}else if(op.equals("KILL")) {
					int pid = sc.nextInt();
					Process p = search(root, pid);
					p.isopen = false;
				}else {
					int pid = sc.nextInt();
					Process p = search(root,pid);
					if(p!=null) {
						System.out.println("Yes");
					}else {
						System.out.println("No");
					}
				}
			}
			
		}
		sc.close();
	}

	static class Process{
		int pid;
		boolean isopen = true;
		ArrayList<Process> son = new ArrayList<Process>();
		public Process(int pid) {
			super();
			this.pid = pid;
		}
	}
	
	static Process search(Process root,int pid) {

		Queue<Process> q = new LinkedList<Process>();
		if(root.isopen) {
			q.add(root);	
		}
		while(q.size()!=0) {
			Process p = q.peek();
			q.remove();
			if(p.pid==pid) {
				return p;
			}
			for(int i = 0;i<p.son.size();i++) {
				if(p.son.get(i).isopen) {
					q.add(p.son.get(i));
				}
			}
		}

		return null;
	}
}

第四题

网络传输
题目描述

网络的高效互联与智能传输是提升海量用户服务请求映射效率的重要措施。在这个任务中,你要用最少的传输时间,将特定的数据源发送到指定的网络节点中。
我们给定的网络一共包含N个节点(从1到N编号),其中节点1为数据源。网络中有M条无向边(u,v,w),表示一条传输线连接节点u和节点v,且数据通过这条传输线的平均时间为w。由于传送机制的限制,当一个节点接收到数据之后,它只能选择与它互连的一个节点,并将数据转发到该节点。节点1在初始化时只会发送一次数据,但在传输过程中它可以作为转发节点。
网络中有k个目标节点,你需要计算出该数据从节点1传送到所有K歌节点所需要的最短时间。注意目标节点可以按任意顺序进行传送,数据也可以多次经过同一节点。

输入格式

输入数据第一行是一个整数T(T<=5),表示测试数据的组数。
对于每组测试数据:
第一行是三个正整数N,M,K(2<=N<=1000,1<=M<=N(N-1)/2,K<=10),分别表示节点数,边数和目标节点数。
接下来M行,每行三个整数u,v,w(1<=u,v<=N, 0<=w<=1000,u!=v)。如上所述给出每条传输线。任意两个网络节点之间最多只会有一条边相连。
最后一行是K个整数,给出所有的目标节点的编号,所有目标节点的编号都在2到N之间。

输出格式

对于每组测试数据,输出数据传送到所有K个目标节点的最短时间。

样例输入

2
3 2 2
1 3 1
1 2 3
2 3
6 6 4
1 5 1
5 6 2
2 1 20
2 3 5
3 4 5
6 3 1
2 3 4 6

样例输出

5
19

import java.util.Scanner;

public class i1404 {

	static int min = Integer.MAX_VALUE;
	static int[][] dis;
	static int k;
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt();
		for(int t=0;t<T;t++) {
			int n =sc.nextInt();
			int m =sc.nextInt();
			k =sc.nextInt();
			dis = new int[n+1][n+1];
			min = Integer.MAX_VALUE;
			for(int i = 1;i<=n;i++) {
				for(int j = 1;j<=n;j++) {
					if(i == j) {
						dis[i][j] = 0;
					}else {
						dis[i][j] = Integer.MAX_VALUE/2;
					}
				}
			}
			for(int i = 0;i<m;i++) {
				int u = sc.nextInt();
				int v = sc.nextInt();
				int w = sc.nextInt();
				dis[u][v] = w;
				dis[v][u] = w;
			}

			for(int o = 1;o<=n;o++) {
				for(int i = 1;i<=n;i++) {
					for(int j = 1;j<=n;j++) {
						if(dis[i][o]!=Integer.MAX_VALUE/2&&dis[o][j]!=Integer.MAX_VALUE/2&&(dis[i][o]+dis[o][j]<dis[i][j])) {
							dis[i][j] = dis[i][o]+dis[o][j];
							dis[j][i] = dis[i][o]+dis[o][j];
						}
					}
				}
			}

			
			int[] a = new int[k];
			for(int i = 0;i<k;i++) {
				a[i] = sc.nextInt();
			}
			
			//全排列
			perm(a,0,k-1);
			System.out.println(min);
 		}
		sc.close();
	}

	static void perm(int[] a,int p,int q) {
		if(p == q) {
			calculate(a);
		}else {
			for(int i = p;i<=q;i++) {
				swap(a,p,i);
				perm(a,p+1,q);
				swap(a,p,i);
			}
		}
	}
	
	static void calculate(int[] a) {
		int sum = 0;
		int pre = 1;
		for(int o = 0;o<k;o++) {
			sum+=dis[pre][a[o]];
			pre = a[o];
		}
		if(sum<min) {
			min = sum;
		}
	}
	
	static void swap(int[] a,int p,int q) {
		int temp = a[p];
		a[p] = a[q];
		a[q] = temp;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值