[京东2017实习生笔试] 终结者C
原题: http://exercise.acmcoder.com/online/online_judge_ques?ques_id=4401&konwledgeId=41
时间限制 C/C++语言:1000MS其它语言:3000MS
内存限制 C/C++语言:65536KB其它语言:589824KB
题目描述
收到情报,有批新造的机器人要运输到前线。小C将去破坏机器人的运输。小C将激光炮放置在公路的一旁,等运输车经过的时候发射(假设激光炮一定可以射穿车辆)。由于能源有限,激光炮只能发射两次。可以认为激光炮放在坐标轴的原点处,并向y轴正方向发射。每辆运输车可以看作是一个矩形,起始的x轴坐标为Xi ,所有的车均位于第一象限,长度为Li,速度为1,朝x轴负方向运动。即经过t时间后,该车车头的x坐标为Xi-t,车尾坐标为Xi-t+Li 。只要打中车的任何一个部分就算击中。
请你算算,他在哪两个时刻发射,才能摧毁最多的运输车。
输入
第一行一个正整数 n ( 2≤N≤200 ),表示运输个的数量。
接下来n行,每行两个整数X和L(1≤X、L≤109),表示一辆车的x轴坐标和长度。
输出
输出最多可以摧毁的运输车数量。
样例输入
4
2 2
3 1
5 2
样例输出
4
思路
暴力枚举。所有车相对不对,可以认为是静止的。枚举所有可能的2个狙击位置,位置均选在车头(或车尾)。枚举所有可能的2个车头位置即可覆盖所有的情况,因为用扫描线从左向右扫过所有车辆,穿过车辆的个数的变化位置一定是发生在某车的车头或车尾,车尾导致个数变小,车头导致个数变大。因此枚举所有可能的车头或车尾位置即可。
代码
1 import java.util.Scanner; 2 3 public class Main { 4 5 public static boolean hit(int[][] itv, int x, int carIx) { 6 return itv[carIx][0] <= itv[x][0] && itv[x][0] <= itv[carIx][1]; 7 } 8 9 public static int count(int[][] itv, int i, int j) { 10 int cnt = 0; 11 for (int k = 0; k < itv.length; k++) { 12 if (hit(itv, i, k) || hit(itv, j, k)) { 13 cnt++; 14 } 15 } 16 return cnt; 17 } 18 19 public static int solve(int[][] itv) { 20 final int n = itv.length; 21 int max = 0; 22 for (int i = 0; i < n; i++) { 23 for (int j = i + 1; j < n; j++) { 24 max = Math.max(max, count(itv, i, j)); 25 } 26 } 27 return max; 28 } 29 30 public static void main(String[] args) { 31 Scanner sc = new Scanner(System.in); 32 int n = sc.nextInt(); 33 int[][] itv = new int[n][2]; 34 for (int i = 0; i < n; i++) { 35 int x = sc.nextInt(); 36 int l = sc.nextInt(); 37 itv[i][0] = x; 38 itv[i][1] = x + l; 39 } 40 41 System.out.println(solve(itv)); 42 } 43 }