京东9.11笔试 T1 机械手打字耗时 T2 正运行的服务数

第一题

 * 你在使用一个特殊的键盘输入一个字符串。键盘是一个矩形网格的形状,有各种不同的排列,
 * 每个按键上的字符互不相同,最多有 94 个按键(除空格外共有 94 个可见 ASCII 字符,ASCII 码为 33~126)。
 * 你需要操作一个机械手来点击这个键盘,机械手可以上下左右移动,
 * 每移动一格耗时 x,移动过程中(不包括一开始或者点击前后)转向耗时 y,每次点击键盘耗时 z。
 * 一开始,机械手位于左上角。请计算打完这个字符串最少需要多少时间
public class Main {
	private static int x, y, z;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		x = sc.nextInt();//移动
		y = sc.nextInt();//转向
		z = sc.nextInt();//点击
		String t = sc.nextLine();//读掉换行
		char[][] matrix = new char[n][m];
		Map<Character, int[]> map = new HashMap<>();
		for(int i = 0; i < n; i++) {
			String s = sc.nextLine();
			for(int j = 0; j < m; j++) {
				matrix[i][j] = s.charAt(j);
				map.put(s.charAt(j), new int[] {i, j});
			}
		}
		
		String str = sc.nextLine();
		long res = 0;
		int i = 0, j = 0;
		for(char c : str.toCharArray()) {
			int[] arr = map.get(c);
			int p = arr[0];
			int q = arr[1];
			res += getTime(i, j, p, q);
			i = p;
			j = q;
		}
		System.out.println(res);
	}
	private static long getTime(int i, int j, int p, int q) {//从(i, j)->(p, q)
		if(i == p && j == q) return z;//原地点击
		if(i == p) return Math.abs(q - j) * x + z;//同行移动+点击
		if(j == q) return Math.abs(p - i) * x + z;
		return Math.abs(q - j) * x + Math.abs(p - i) * x + y + z;//移动+转向+点击
	}
}


第二题 只过了27%,有没有大佬指点一下

在一个 systemd units 中,可以使用 Requires=… 的语法来引入依赖,
当服务 a 引入了服务 b 作为依赖之后,服务 a 启动时 b 会随之启动,b 停止时 a 会随之停止。
本题会给你 n 个服务和它们之间的依赖关系,一开始所有服务都处于停止状态,
然后进行若干次启动和停止操作,你需要在每一次操作后输出当前正在运行的服务数量。
假设所有服务都能稳定运行、正常启动和退出。
为了简化输入,所有服务名使用序号(1~n)代替。
可以启动正在运行的程序,也可以停止已经停止的程序,这样的操作将不会造成任何变化。

输入:第一行两个空格隔开的整数 n, q,表示服务的数量和询问的数量,1 <= n, q <= 500。
下面 n 行,其中的第 i 行第一个整数 c 表示第 i 个服务所依赖的服务数量,后面 c 个整数表示它所依赖的各个服务,保证这 c 个整数在 1~n 范围内,互不相等且都不等于 i。
下面 q 行,每行两个空格隔开的整数 x, y。x 为 1 或 0,1 表示启动服务,0 表示停止服务。y 表示启动或停止的服务的序号。
输出:每一次操作后输出当前正在运行的服务数量

只过了27%,考虑了循环依赖等,自测均无问题,正在运行的服务数 <= n <= 500 也不可能越界
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int q = sc.nextInt();
		Map<Integer, LinkedList<Integer>> openMap = new HashMap<>();//(服务i, 服务i依赖的服务们)
		Map<Integer, LinkedList<Integer>> closeMap = new HashMap<>();//(服务i, 服务i被哪些服务依赖)
		for(int i = 1; i <= n; i++) {
			int c = sc.nextInt();
			LinkedList<Integer> list = new LinkedList<>();
			for(int j = 0; j < c; j++) {
				int task = sc.nextInt();
				list.add(task);
				LinkedList<Integer> closeList = closeMap.get(task);
				if(closeList == null) {
					closeList = new LinkedList<>();
					closeList.add(i);
					closeMap.put(task, closeList);
				}else {
					closeMap.get(task).add(i);
				}
			}
			openMap.put(i, list);
		}
		
		System.out.println(openMap);
		System.out.println(closeMap);
		int[] status = new int[n + 1];//每个服务的状态
		int count = 0;//运行的服务数量
		for(int i = 0; i < q; i++) {
			int x = sc.nextInt();
			int y = sc.nextInt();
			if(x == 1) {//开启y和y依赖的所有服务
				if(status[y] != 1) {
					status[y] = 1;
					count++;
					Queue<Integer> openQueue = openMap.get(y);
					while(openQueue.size() > 0) {
						Integer cur = openQueue.poll();
						if(status[cur] == 1) continue;//说明已经开了
						status[cur] = 1;
						count++;
						List<Integer> open = openMap.get(cur);
						if(open != null) openQueue.addAll(open);
					}	
				}
			}else {//关闭y和依赖y的所有服务
				if(status[y] != 0) {
					status[y] = 0;
					count--;
					Queue<Integer> closeQueue = closeMap.get(y);
					while(closeQueue.size() > 0) {
						Integer cur = closeQueue.poll();
						if(status[cur] == 0) continue;//说明已经开了
						status[cur] = 0;
						count--;
						List<Integer> close = closeMap.get(cur);
						if(close != null) closeQueue.addAll(close);
					}	
				}
			}
			System.out.println(count);
		}
	}
	
}




#京东##笔经#
全部评论
用两个哈希表存, 一个正向存 require, 另一个反向存, 然后用广度优先搜索处理服务
点赞 回复 分享
发布于 2021-09-11 21:23

相关推荐

Pandaileee:校友加油我现在也只有一个保底太难了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务