B. 击毁战车

原题链接

B. 击毁战车

题目大意

m ( 1 ≤ m ≤ 1000 ) m(1\le m\le 1000) m(1m1000)辆战车,最开始,都处于 p o s i pos_i posi的位置,每秒能移动 s p e e d i speed_i speedi位置(只能从小坐标往大坐标走)。原点上有一炮台。炮台有 n n n颗炮弹,在时刻0开始就可以发射炮弹,而且发射的顺序是你来确定的,每次只能发射一颗,一颗炮弹只能用一次。每个炮弹都有一个休息时间 r e s t i rest_i resti,如果在某次发射了第 i i i颗炮弹,要间隔 r e s t i rest_i resti后才能在发射。一颗炮弹只能击毁范围 0 ∼ d 0\sim d 0d位置内的一辆战车。求最多可以击毁多少辆战车。

解题思路

这一题,我们考虑贪心。对于每一辆车而言,都有一个距离出界剩余的时间,若想打到尽量多的战车,则肯定得优先打距离出界剩余时间最小的战车。所以只要我们按照距离出界剩余时间排序之后,按照顺序打战车就可以得到最优解了。

代码实现

#include<bits/stdc++.h>
using namespace std;
struct node{
    
    
	long long id,ot;
} t[1010];
long long s,ans,rest[1010],speed[1010],pos[1010],n,m,d;
bool pd(node q,node h){
    
    
	return q.ot<h.ot;//按照出界时间由小到大排序
}
int main()
{
    
    
	//注意freopen!!!
	freopen("catch.in","r",stdin);
	freopen("catch.out","w",stdout);
	cin>>n>>m>>d;//输入子弹个数,战车个数和射程
	for(long long i=1;i<=n;i++)
		cin>>rest[i];
	sort(rest+1,rest+1+n);//贪心,优先间隔时间小的
	for(long long i=1;i<=m;i++){
    
    
		cin>>pos[i]>>speed[i];
		t[i].id=i;//记录编号
		if(pos[i]>d)
			t[i].ot=-1;//记录无法打到
		else
			t[i].ot=(d-pos[i])/speed[i];//使用剩余路程除以速度,得到剩余时间(注意需要使用double)
	}
	sort(t+1,t+m+1,pd);//贪心,优先剩余时间小的
	int j=1;
	for(long long i=1;i<=m;i++){
    
    
		if(s>t[m].ot)//剩余时间最大的都打不到了
			break;
		if(s>t[i].ot)//无法打到当前战车(直接下一个)
			continue;
		ans++;//能打到当前战车,答案加一
		s=s+rest[j];//时间加上间隔时间
		j++;//下一个子弹
		if(j>n)//子弹用完了
			break;
	}
	cout<<ans;
}

样例

输入

3 3 3
3
2
1
4 1
1 1
2 1

输出

2

猜你喜欢

转载自blog.csdn.net/weixin_41247488/article/details/120688677