京东实习笔试——终结者C

题目大意:在发射两个激光炮时,如何打到最多数量的战车。

解题思路:下面给出两个答案,其中第一个是我自己的程序,没有通过全部的测试用例(测试超过50%),但是时间复杂度要比官方给的答案的时间复杂度小。

方法一:就是将所有战车所包含的数字加入到一个哈希表中,以数字为键,以出现的次数为值。最后找出最大的值value和对应的key。然后,遍历所有战车车型包含的值(x--x+l),如果key包含在其中,则键为(x--x+l)的所有对应的值都减一。最后找出第二大的value1值。将两个value值相加,得到的结果可能是最大的数量的战车。这个思路简单,但是存在问题,就是同时出现两个相同的不相邻的value值,再求解第二大的value1时,可能出现两种情况,此时结果就不唯一了。这就是导致没有全部通过的原因。

方法二:就是官方给出的答案,三层遍历,针对每辆车的范围进行判断,通过每辆车时能够发射到的所有车的数量,形成一个集合,找出最大值。

package 京东;

import java.util.Map.Entry;
import java.util.HashMap;
import java.util.Scanner;

/**
 * 题目描述:
 * 收到情报,有批新造的机器人要运输到前线。小C将去破坏机器人的运输。小C将激光炮放置在公路的一旁,等运输车经过的时候发射(假设激光炮一定可以射穿车辆)。由于能源有限,激光炮只能发射两次。可以认为激光炮放在坐标轴的原点处,并向y轴正方向发射。每辆运输车可以看作是一个矩形,起始的x轴坐标为Xi,所有的车均位于第一象限,长度为Li,速度为1,朝x轴负方向运动。即经过t时间后,该车车头的x坐标为Xi-t,车尾坐标为Xi-t+Li。只要打中车的任何一个部分就算击中。 请你算算,他在哪两个时刻发射,才能摧毁最多的运输车。
 */
public class Q2017_终结者C_通过50 {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()){
			HashMap<Integer, Integer> hashMap = new HashMap<>();
			
			int n = sc.nextInt();
			int[][] nums = new int[n][2];
			for(int i=0; i<1000000; i++){
				hashMap.put(i, 0);
			}
			
			for(int i=0; i<n; i++){
				int x = sc.nextInt();
				int l = sc.nextInt();
				nums[i][0] = x;
				nums[i][1] = l;
				for(int j=x; j<=x+l; j++){
					hashMap.put(j, (hashMap.get(j))+1);
				}				
			}
			int result1 = 0;
			int key1 = 0;
			for (Entry<Integer, Integer> e : hashMap.entrySet()) {
				int value = e.getValue();
				int key = e.getKey();
				if(value > result1){
					result1 = value;
					key1 = key;
				}
			}
			
			for (int[] is : nums) {
				int x = is[0];
				int l = is[1];
				if(key1>=x && key1<=x+l){
					for(int k=x; k<=x+l; k++){
						hashMap.put(k, (hashMap.get(k))-1);
					}
				}
			}
			
			int result2 = 0;
			for (Entry<Integer, Integer> e : hashMap.entrySet()) {
				int value = e.getValue();
				if(value > result2){
					result2 = value;
				}
			}
			
			System.out.println(result1+result2);
			
		}
		sc.close();
	}

}
方法二代码:

package 京东;
import java.util.Scanner;

public class Q2017_终结者C2_通过100 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while(in.hasNext()) {
			int n = in.nextInt();
			int[] ls = new int[n];
			int[] le = new int[n];
			for(int i=0; i<n; i++) {
				ls[i] = in.nextInt();
				le[i] = ls[i] + in.nextInt();
			}
			
			int h = 0;
			for(int i=0; i<n; i++) {
				for(int j=i+1; j<n; j++) {
					int hi = 0;
					for(int k=0; k<n; k++) {
						if((ls[k] <= ls[i] && le[k] >= ls[i]) 
								|| (ls[k] <=ls[j] && le[k] >= ls[j])) {
							hi++;
						}
					}
					if(hi > h) h = hi;
				}
			}
			System.out.println(h);
		}
		in.close();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值