Cpp环境【NOIP practice】【BSOJ1878】【Vijos1172】 山头狙击战
2016-07-30 09:08
399 查看
【问题描述】
Lucky为了掩护大部队,单枪匹马同敌人周旋,后来被敌人包围在某山头……等等,为什么怎么听怎么像狼牙山五壮士!不过不用着急,这次Lucky携带了足够的弹药,完全可以将涌上来的敌人一个一个干掉。Lucky是个神枪手,只要他的枪膛中有子弹,他就能将在他射程m(用从敌人位置到山头的直线距离算)以内的一个敌人瞬间射杀。但如果在射程内没有敌人,出于节约子弹考虑和面子问题,Lucky会等待敌人靠近然后射击。
正当Lucky为自己的强大而自我膨胀时,他忽然发现了一个致命的失误:他携带的枪是单发枪,每射出一发子弹都必须花k秒钟的时间装子弹。而凶残的敌人才不会花时间等你换子弹呢。他们始终在以1m/s的速度接近山头。而如果在一个敌人到达山头时Lucky无法将他击毙,那么我们可怜的Lucky就将牺牲在敌人的刺刀下。现在Lucky用心灵感应向你发出求助:要保住自己的性命并且歼灭所有敌人,Lucky最多只能用多少时间给枪装上一发子弹?
说明:假设一开始Lucky的枪中就有一发子弹,并且一旦确定一个装弹时间,Lucky始终会用这个时间完成子弹的装卸。希望你能帮助Lucky脱离险境。
【输入格式】
第一行有两个整数n和m,n代表敌人个数,m代表Lucky的射程。接下来有n行,每行一个整数di,代表每个敌人一开始相对山头的距离(单位为米)。
【输出格式】
仅有一个整数,代表Lucky的换弹时间(单位为秒)。
【输入样例】
6 100
236
120
120
120
120
120
【输出样例】
25
【数据范围】
50%的数据有:2<=n<=1000
100%的数据有:2<=n<=100,000; 1<=m<=10,000,000;1<=di<=10,000,000
【思路梳理】
不解释为什么使用二分猜答案和二分猜答案的细节,直接描述check函数的写法。
首先肯定是先排序确定好每一个敌人的距离。贪心地,这个顺序也是我们依次击毙敌人的顺序(肯定优先射杀更近的敌人来为击杀后面的敌人腾出更多时间)。
那么接下来怎么办?
最容易想到的办法是模拟,用一个新的数组dist1来判断Lucky能否在他抵达山头之前击毙。但这样显得复杂,而且有点慢。
于是考虑使用一个time计时器来记录当前的时间。如果最近敌人在射程m以外,Lucky就要等待他进入射程,计时器加上这个敌人进入射程的时间(值得一提的是这个时间是相对于开始战斗的时间,距离是相对于初始距离而言)。如果某一时刻time>=dist[i],击毙这一名敌人的时间已经大于了他接近神射手所需的时间,说明Lucky已经阵亡,这个装填时间太长。每一次击杀敌人后,Lucky都要装弹,time+reload_time。
【Cpp代码】
#include<cstdio> #include<iostream> #include<vector> #include<algorithm> #define maxn 100005 using namespace std; int n,m; vector<int>dist; bool judge(int reload_time) { int time=0;//从开始到击杀下一个敌人所需要的时间 for(int i=0;i<n;i++) { if(time>dist[i]) return false;//击杀第i个敌人的时间已经大于了他接近神射手所需的时间 if(time<dist[i]-m) time=dist[i]-m;//下一个最近的敌人还没有进入射程,Lucky等待他进入射程 time+=reload_time;//击毙第i名敌人,Lucky装填子弹 } return true; } void solve() { int s=0,d=m,ans; while(s<=d) { int mid=s+d>>1; if(judge(mid)) ans=mid,s=mid+1; else d=mid-1; } printf("%d",ans); } int main() { //freopen("in.txt","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); dist.push_back(x); } sort(dist.begin(),dist.end()); solve(); return 0; }
相关文章推荐
- C++中const用法总结
- CPP 虚函数、虚函数表及虚拟继承(转)
- Deploying Control Plane Policing
- Thrift的required和optional源码分析
- c++中extern关键字详解 知识补充笔记
- MBProgressHUD的基本使用
- 意外的结果-C++中的移位操作
- VIJOS P1040 高精度乘法
- MFC自定义类访问主窗口控件
- LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main 问题解决
- 单向链表LinkedList的使用
- cpp函数返回对象&&数组
- 继承、组合、委托
- vim配置
- LIB和DLL的区别与使用
- VIJOS P1000 A+B Problem
- Learn note(cpp): take care when use new in a code block.
- 如果在主串Tag的第pos个位置后存在
- BF算法
- 一个悲伤的gcc故事