首页 > 代码库 > [京东2017实习生笔试] 终结者C

[京东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 }

 

[京东2017实习生笔试] 终结者C