京东笔试题-激光炮(分析转换简化问题)

http://exercise.acmcoder.com/online/online_judge_ques?ques_id=4401&konwledgeId=41

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

请你算算,他在哪两个时刻发射,才能摧毁最多的运输车。

解析:

       假设矩形(车辆位置不变),两个激光炮在动,分析出“两个激光炮能打最多的车的位置,一定等价于在某个矩形框的最左边位置”是转化问题的关键。但摧毁最多运输车的情况下,两个发射时刻的位置不是唯一的,这也是题目的漏洞所在。故只需遍历所有任意组合的两个矩形框,然后再去遍历哪些车能被打到,复杂度为o(n3).

     困扰我的地方是,这两个激光炮可能打到的是同一辆车,故要排除重复的情况。所以就有人说,先遍历一遍,保存打到的矩形车数目,然后把这些车给剔除掉,然后在遍历一遍,得到另外一个数组,然后将两个数组相加,得到最大值。这样会需要o(n2)的内存空间。方案上是可行的。但还是要挖掘出激光炮的位置一定等价于在矩形框的最左侧位置。

    当然在最右侧位置也是对的。


 

#include<cstdio>
#include<cstring>

int a[205], b[205], c[205];
bool canShoot(int w, int e){//激光炮在第w个矩形框的最左边能否打到第e个车
	return a[e] <= a[w] && b[e] >= a[w];
}
int n;
int getShootNumber(int w, int e){
	int re = 0;
	for (int i = 1; i <= n; i++)//遍历所有的矩形车,看是否能被w,e位置处的激光炮其中之一打到
		if (canShoot(w, i) || canShoot(e, i))re++;
	return re;
}
void work(){
	scanf("%d", &n);
	for (int i = 1; i <= n; i++){
		int l;
		scanf("%d %d", &a[i], &l);
		b[i] = a[i] + l;
	}
	int ans = 0;
	for (int i = 1; i <= n; i++)
		for (int j = i + 1; j <= n; j++){
			int k = getShootNumber(i, j);
			if (k>ans)ans = k;
		}
	printf("%d\n", ans);
}
int main(){
	work();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值